home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 4287 / 4287.xpi / chrome / splitbrowser.jar / content / splitbrowser / splitbrowser.xml < prev    next >
Extensible Markup Language  |  2009-11-05  |  79KB  |  2,297 lines

  1. <?xml version="1.0"?>
  2. <!DOCTYPE bindings SYSTEM "chrome://splitbrowser/locale/">
  3. <bindings id="splitbrowserBindings"
  4.     xmlns="http://www.mozilla.org/xbl"
  5.     xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
  6.     xmlns:xbl="http://www.mozilla.org/xbl">
  7.  
  8. <binding id="contents-in-container" display="xul:vbox">
  9.     <implementation>
  10.         <property name="parentContainer" readonly="true">
  11.             <getter><![CDATA[
  12.                 var container = this.parentNode;
  13.                 while (container.localName != 'subbrowser-container' &&
  14.                         container.parentNode)
  15.                 {
  16.                     container = container.parentNode;
  17.                 }
  18.  
  19.                 return (container.localName == 'subbrowser-container') ? container : null ;
  20.             ]]></getter>
  21.         </property>
  22.  
  23.         <property name="flexibleParent" readonly="true">
  24.             <getter><![CDATA[
  25.                 var c = this;
  26.                 while (
  27.                     c &&
  28.                     c != document.documentElement &&
  29.                     !c.nextSibling &&
  30.                     !c.previousSibling
  31.                     )
  32.                     c = c.parentNode;
  33.  
  34.                 return c == document.documentElement ? null : c ;
  35.             ]]></getter>
  36.         </property>
  37.  
  38.         <property name="contentCollapsed" readonly="true"
  39.             onget="return this.vContentCollapsed || this.hContentCollapsed;"/>
  40.         <property name="contentCompletelyCollapsed" readonly="true"
  41.             onget="return this.vContentCompletelyCollapsed || this.hContentCompletelyCollapsed;"/>
  42.  
  43.         <field name="lastwidth">-1</field>
  44.         <field name="lastheight">-1</field>
  45.     </implementation>
  46. </binding>
  47.  
  48.  
  49.  
  50. <binding id="container" extends="#contents-in-container">
  51.     <!--content orient="vertical">
  52.         <xul:vbox anonid="vertical-container" flex="1"
  53.             class="vertical-container">
  54.             <xul:hbox anonid="horizontal-container" flex="1"
  55.                 class="horizontal-container"/>
  56.         </xul:vbox>
  57.     </content-->
  58.  
  59.     <implementation>
  60. <!--
  61.         <field name="hContainer">null</field>
  62.         <field name="vContainer">null</field>
  63. -->
  64.         <constructor><![CDATA[
  65.             if (
  66.                 this.vContainer ||
  67.                 this.localName != 'subbrowser-container' ||
  68.                 (
  69.                     this.hasChildNodes() &&
  70.                     this.firstChild.getAttribute('class') == 'vertical-container'
  71.                 )
  72.                 )
  73.                 return;
  74.  
  75.             this.vContainer = document.createElement('vbox');
  76.             this.vContainer.setAttribute('class', 'vertical-container');
  77.             this.vContainer.setAttribute('flex', 1);
  78.             this.appendChild(this.vContainer);
  79.  
  80.             this.hContainer = document.createElement('hbox');
  81.             this.hContainer.setAttribute('class', 'horizontal-container');
  82.             this.hContainer.setAttribute('flex', 1);
  83.             this.vContainer.appendChild(this.hContainer);
  84.  
  85.         ]]></constructor>
  86.  
  87.         <property name="vContentCollapsed" readonly="true"
  88.             onget="return this.vContainer.vContentCollapsed || (this.hContainer ? this.hContainer.vContentCollapsed : false );"/>
  89.         <property name="hContentCollapsed" readonly="true"
  90.             onget="return this.vContainer.hContentCollapsed || (this.hContainer ? this.hContainer.hContentCollapsed : false );"/>
  91.  
  92.         <property name="vContentCompletelyCollapsed" readonly="true"
  93.             onget="return this.vContainer.vContentCompletelyCollapsed && (this.hContainer ? this.hContainer.vContentCompletelyCollapsed : false );"/>
  94.         <property name="hContentCompletelyCollapsed" readonly="true"
  95.             onget="return this.vContainer.hContentCompletelyCollapsed && (this.hContainer ? this.hContainer.hContentCompletelyCollapsed : false );"/>
  96.     </implementation>
  97.  
  98.     <handlers>
  99.         <handler event="mousedown"><![CDATA[
  100.             var newEvent = document.createEvent('Events');
  101.             newEvent.force = true;
  102.             newEvent.initEvent('SubBrowserExitContentAreaEdge', false, true);
  103.             this.dispatchEvent(newEvent);
  104.         ]]></handler>
  105.     </handlers>
  106. </binding>
  107.  
  108. <binding id="horizontal-container" display="xul:hbox">
  109.     <implementation>
  110.         <property name="contentCollapsed" readonly="true"
  111.             onget="return this.vContentCollapsed || this.hContentCollapsed;"/>
  112.         <property name="vContentCollapsed" readonly="true">
  113.             <getter><![CDATA[
  114.                 var collapsed = 0;
  115.  
  116.                 var nodes = this.childNodes;
  117.                 for (var i = 0, maxi = nodes.length; i < maxi; i = i+2)
  118.                     if (nodes[i].vContentCollapsed)
  119.                         return true;
  120.  
  121.                 return false;
  122.             ]]></getter>
  123.         </property>
  124.         <property name="hContentCollapsed" readonly="true">
  125.             <getter><![CDATA[
  126.                 var collapsed = 0;
  127.  
  128.                 var nodes = this.childNodes;
  129.                 for (var i = 0, maxi = nodes.length; i < maxi; i = i+2)
  130.                     if (nodes[i].hContentCollapsed)
  131.                         return true;
  132.  
  133.                 return false;
  134.             ]]></getter>
  135.         </property>
  136.  
  137.         <property name="contentCompletelyCollapsed" readonly="true"
  138.             onget="return this.vContentCompletelyCollapsed || this.hContentCompletelyCollapsed;"/>
  139.         <property name="vContentCompletelyCollapsed" readonly="true">
  140.             <getter><![CDATA[
  141.                 var expanded = 0;
  142.  
  143.                 var nodes = this.childNodes;
  144.                 for (var i = 0, maxi = nodes.length; i < maxi; i = i+2)
  145.                     if (!nodes[i].vContentCompletelyCollapsed)
  146.                         return false;
  147.  
  148.                 return true;
  149.             ]]></getter>
  150.         </property>
  151.         <property name="hContentCompletelyCollapsed" readonly="true">
  152.             <getter><![CDATA[
  153.                 var expanded = 0;
  154.  
  155.                 var nodes = this.childNodes;
  156.                 for (var i = 0, maxi = nodes.length; i < maxi; i = i+2)
  157.                     if (!nodes[i].hContentCompletelyCollapsed)
  158.                         return false;
  159.  
  160.                 return true;
  161.             ]]></getter>
  162.         </property>
  163.     </implementation>
  164. </binding>
  165.  
  166. <binding id="vertical-container" display="xul:vbox">
  167.     <implementation>
  168.         <property name="contentCollapsed" readonly="true"
  169.             onget="return this.vContentCollapsed || this.hContentCollapsed;"/>
  170.         <property name="vContentCollapsed" readonly="true">
  171.             <getter><![CDATA[
  172.                 var collapsed = 0;
  173.  
  174.                 var nodes = this.childNodes;
  175.                 for (var i = 0, maxi = nodes.length; i < maxi; i = i+2)
  176.                     if (nodes[i].vContentCollapsed)
  177.                         return true;
  178.  
  179.                 return false;
  180.             ]]></getter>
  181.         </property>
  182.         <property name="hContentCollapsed" readonly="true">
  183.             <getter><![CDATA[
  184.                 var collapsed = 0;
  185.  
  186.                 var nodes = this.childNodes;
  187.                 for (var i = 0, maxi = nodes.length; i < maxi; i = i+2)
  188.                     if (nodes[i].hContentCollapsed)
  189.                         return true;
  190.  
  191.                 return false;
  192.             ]]></getter>
  193.         </property>
  194.  
  195.         <property name="contentCompletelyCollapsed" readonly="true"
  196.             onget="return this.vContentCompletelyCollapsed || this.hContentCompletelyCollapsed;"/>
  197.         <property name="vContentCompletelyCollapsed" readonly="true">
  198.             <getter><![CDATA[
  199.                 var expanded = 0;
  200.  
  201.                 var nodes = this.childNodes;
  202.                 for (var i = 0, maxi = nodes.length; i < maxi; i = i+2)
  203.                     if (!nodes[i].vContentCompletelyCollapsed)
  204.                         return false;
  205.  
  206.                 return true;
  207.             ]]></getter>
  208.         </property>
  209.         <property name="hContentCompletelyCollapsed" readonly="true">
  210.             <getter><![CDATA[
  211.                 var expanded = 0;
  212.  
  213.                 var nodes = this.childNodes;
  214.                 for (var i = 0, maxi = nodes.length; i < maxi; i = i+2)
  215.                     if (!nodes[i].hContentCompletelyCollapsed)
  216.                         return false;
  217.  
  218.                 return true;
  219.             ]]></getter>
  220.         </property>
  221.     </implementation>
  222. </binding>
  223.  
  224. <binding id="toplevel-container" extends="#container">
  225.     <content orient="vertical">
  226.         <xul:vbox anonid="primary-browser-inner-container" flex="1">
  227.             <xul:vbox anonid="vertical-container" flex="1"
  228.                 class="vertical-container">
  229.                 <xul:hbox anonid="horizontal-container" flex="1"
  230.                     class="horizontal-container">
  231.                     <xul:vbox anonid="primary-browser-wrapper" flex="1"
  232.                         class="primary-browser-wrapper"
  233.                         name="_top">
  234.                         <children/>
  235.                     </xul:vbox>
  236.                 </xul:hbox>
  237.             </xul:vbox>
  238.         </xul:vbox>
  239.     </content>
  240.  
  241.     <implementation>
  242.         <property name="hContainer" readonly="true"
  243.             onget="try { return document.getAnonymousElementByAttribute(this, 'anonid', 'horizontal-container'); } catch(e) { return null; }"/>
  244.         <property name="vContainer" readonly="true"
  245.             onget="try { return document.getAnonymousElementByAttribute(this, 'anonid', 'vertical-container'); } catch(e) { return null; }"/>
  246.         <property name="contentWrapper" readonly="true"
  247.             onget="try { return document.getAnonymousElementByAttribute(this, 'anonid', 'primary-browser-wrapper'); } catch(e) { return null; }"/>
  248.  
  249.         <property name="innerContainer" readonly="true"
  250.             onget="try { return document.getAnonymousElementByAttribute(this, 'anonid', 'primary-browser-inner-container'); } catch(e) { return null; }"/>
  251.     </implementation>
  252. </binding>
  253.  
  254.  
  255.  
  256. <binding id="subbrowser-base" extends="#contents-in-container">
  257.     <implementation>
  258.         <property name="rightOffset" readonly="true">
  259.             <getter><![CDATA[
  260.                 var win = (this.browser || gBrowser).contentWindow;
  261.                 return (win.scrollMaxY > 0) ? SplitBrowser.scrollbarSize : 0 ;
  262.             ]]></getter>
  263.         </property>
  264.  
  265.         <property name="bottomOffset" readonly="true">
  266.             <getter><![CDATA[
  267.                 var win = (this.browser || gBrowser).contentWindow;
  268.                 return (win.scrollMaxX > 0) ? SplitBrowser.scrollbarSize : 0 ;
  269.             ]]></getter>
  270.         </property>
  271.  
  272.         <property name="contentAreaSizeObject" readonly="true">
  273.             <getter><![CDATA[
  274.                 if (!this.browser) return null;
  275.                 var box, retVal;
  276.                 if (this.localName == 'subbrowser') {
  277.                     if (this.browser.localName == 'tabbrowser')
  278.                         box = this.browser.mCurrentBrowser;
  279.                     else
  280.                         box = this.browser;
  281.                 }
  282.                 else
  283.                     box = gBrowser.mCurrentBrowser;
  284.  
  285.                 retVal =  { box : box };
  286.  
  287.                 box = box.boxObject;
  288.                 retVal.x       = box.x;
  289.                 retVal.y       = box.y;
  290.                 retVal.screenX = box.screenX;
  291.                 retVal.screenY = box.screenY;
  292.                 retVal.width   = box.width - this.rightOffset;
  293.                 retVal.height  = box.height - this.bottomOffset;
  294.  
  295.                 retVal.middleX = parseInt(box.x + (box.width / 2));
  296.                 retVal.middleY = parseInt(box.y + (box.height / 2));
  297.                 retVal.middleScreenX = parseInt(box.screenX + (box.width / 2));
  298.                 retVal.middleScreenY = parseInt(box.screenY + (box.height / 2));
  299.  
  300.                 retVal.areaWidth   = parseInt(Math.min(SplitBrowser.addButtonAreaSize, box.width * 0.6));
  301.                 retVal.areaX       = retVal.middleX - parseInt(retVal.areaWidth / 2);
  302.                 retVal.areaScreenX = retVal.middleScreenX - parseInt(retVal.areaWidth / 2);
  303.                 retVal.areaHeight  = parseInt(Math.min(SplitBrowser.addButtonAreaSize, box.height * 0.6));
  304.                 retVal.areaY       = retVal.middleY - parseInt(retVal.areaHeight / 2);
  305.                 retVal.areaScreenY = retVal.middleScreenY - parseInt(retVal.areaHeight / 2);
  306.  
  307.                 return retVal;
  308.             ]]></getter>
  309.         </property>
  310.  
  311.         <property name="src" readonly="true"
  312.             onget="return gBrowser.currentURI.spec;"/>
  313.         <property name="contentWindow"
  314.             readonly="true"
  315.             onget="return gBrowser.contentWindow;"/>
  316.  
  317.         <method name="toggleCollapsed">
  318.             <body><![CDATA[
  319.                 if (this.contentCollapsed)
  320.                     this.expand();
  321.                 else
  322.                     this.collapse();
  323.             ]]></body>
  324.         </method>
  325.  
  326.         <method name="collapse">
  327.             <body><![CDATA[
  328.                 var c = this.flexibleParent;
  329.                 if (!c) return;
  330.  
  331.                 var splitter = c.nextSibling || c.previousSibling;
  332.                 var prop     = (splitter.getAttribute('orient') != 'vertical') ? 'width' : 'height' ;
  333.                 var cProp    = (splitter.getAttribute('orient') != 'vertical') ? 'hContentCollapsed' : 'vContentCollapsed' ;
  334.                 var cCProp   = (splitter.getAttribute('orient') != 'vertical') ? 'hContentCompletelyCollapsed' : 'vContentCompletelyCollapsed' ;
  335.  
  336.                 if (this[cProp]) return;
  337.  
  338.                 var sideBox = this.findSideBox(
  339.                         c,
  340.                         (c.getAttribute('splitter') == 'before' ? -1 : 1 ),
  341.                         (splitter.getAttribute('orient') != 'vertical' ? 'horizontal' : 'vertical' )
  342.                     );
  343.                 if (!sideBox) return;
  344.  
  345. /*
  346. var col = (['red', 'blue', 'green'])[parseInt(Math.random() * 3)];
  347. c.setAttribute('style', 'border: 2px dotted '+col+' !important;');
  348. sideBox.setAttribute('style', 'border: 2px solid '+col+' !important;');
  349. window.setTimeout(function() {
  350. c.removeAttribute('style');
  351. sideBox.removeAttribute('style');
  352. }, 2000);
  353. */
  354.  
  355.                 var origSize = c.boxObject[prop];
  356.                 var sideSize = sideBox.boxObject[prop];
  357.  
  358.                 c['last'+prop] = origSize;
  359.                 c.setAttribute(prop, 0);
  360.                 sideBox.removeAttribute('max'+prop);
  361.                 sideBox.setAttribute(prop, sideSize + origSize);
  362.                 c.setAttribute('max'+prop, 0);
  363.                 this.blur();
  364.  
  365.                 window.setTimeout(function(aThis) {
  366.                     aThis.toggleNavigation(false);
  367.                     aThis.mUpdateToolbarMode();
  368.  
  369.                     var node = c.parentNode;
  370.                     var appcontent = document.getElementById('appcontent');
  371.                     while (node && node != appcontent)
  372.                     {
  373.                         if (cCProp in node && node[cCProp])
  374.                             node.setAttribute('max'+prop, 0);
  375.                         node = node.parentNode;
  376.                     }
  377.                 }, 0, this);
  378.             ]]></body>
  379.         </method>
  380.  
  381.         <method name="expand">
  382.             <parameter name="aForce"/>
  383.             <body><![CDATA[
  384.                 var c = this.flexibleParent;
  385.                 if (!c) return;
  386.  
  387.                 var splitter = c.nextSibling || c.previousSibling;
  388.                 var prop     = (splitter.getAttribute('orient') == 'horizontal') ? 'width' : 'height' ;
  389.                 var cProp    = (splitter.getAttribute('orient') != 'vertical') ? 'hContentCollapsed' : 'vContentCollapsed' ;
  390.  
  391.                 if (!this[cProp]) return;
  392.  
  393.                 var sideBox = this.findSideBox(
  394.                         c,
  395.                         (c.getAttribute('splitter') == 'before' ? -1 : 1 ),
  396.                         (splitter.getAttribute('orient') != 'vertical' ? 'horizontal' : 'vertical' )
  397.                     );
  398.                 if (!sideBox) return;
  399.  
  400. /*
  401. var col = (['red', 'blue', 'green'])[parseInt(Math.random() * 3)];
  402. c.setAttribute('style', 'border: 2px dotted '+col+' !important;');
  403. sideBox.setAttribute('style', 'border: 2px solid '+col+' !important;');
  404. window.setTimeout(function() {
  405. c.removeAttribute('style');
  406. sideBox.removeAttribute('style');
  407. }, 2000);
  408. */
  409.  
  410.                 var origSize = c.boxObject[prop];
  411.                 var sideSize = sideBox.boxObject[prop];
  412.  
  413.                 var node = c;
  414.                 var appcontent = document.getElementById('appcontent');
  415.                 var sideBoxPos = 'before';
  416.                 do {
  417.                     node.removeAttribute('max'+prop);
  418.                     if (node.nextSibling && node.nextSibling.nextSibling == sideBox)
  419.                         sideBoxPos = 'after';
  420.                     node = node.parentNode;
  421.                 }
  422.                 while (node && node != appcontent)
  423.  
  424.                 if (c['last'+prop] === void(0) || c['last'+prop] <= 0)
  425.                     c['last'+prop] = parseInt(sideSize * 2 / 5);
  426.                 c.setAttribute(prop, c['last'+prop]);
  427.                 sideBox.setAttribute(prop, sideSize - (c['last'+prop] - origSize));
  428.                 c['last'+prop] = -1;
  429.  
  430.                 this.clearMaxSizeProp(
  431.                     ((sideBoxPos == 'after') ? sideBox.previousSibling.previousSibling : sideBox.nextSibling.nextSibling ),
  432.                     prop
  433.                 );
  434.  
  435.  
  436.                 window.setTimeout(function(aThis) {
  437.                     aThis.toggleNavigation((aThis.getAttribute('toolbar-navigation') == 'true'));
  438.                     aThis.mUpdateToolbarMode();
  439.                 }, 0, this);
  440.             ]]></body>
  441.         </method>
  442.         <method name="clearMaxSizeProp">
  443.             <parameter name="aNode"/>
  444.             <parameter name="aProp"/>
  445.             <body><![CDATA[
  446.                 aNode.removeAttribute('max'+aProp);
  447.                 if (aNode['last'+aProp]) aNode['last'+aProp] = -1;
  448.                 if (aNode == this) return;
  449.                 for (var i = 0, maxi = aNode.childNodes.length; i < maxi; i = i+2)
  450.                 {
  451.                     this.clearMaxSizeProp(aNode.childNodes[i], aProp);
  452.                 }
  453.             ]]></body>
  454.         </method>
  455.  
  456.  
  457.         <method name="findSideBox">
  458.             <parameter name="aBox"/>
  459.             <parameter name="aDir"/>
  460.             <parameter name="aOrient"/>
  461.             <parameter name="aFindAny"/>
  462.             <body><![CDATA[
  463.                 var cProp  = (aOrient != 'vertical') ? 'hContentCollapsed' : 'vContentCollapsed' ;
  464.  
  465.                 var target = aBox;
  466.                 if (aDir < 0) {
  467.                     while (target && target.previousSibling)
  468.                     {
  469.                         target = target.previousSibling.previousSibling;
  470.                         if (aFindAny || !target[cProp]) return target;
  471.                     }
  472.  
  473.                     target = aBox;
  474.                     while (target && target.nextSibling)
  475.                     {
  476.                         target = target.nextSibling.nextSibling;
  477.                         if (aFindAny || !target[cProp]) return target;
  478.                     }
  479.                 }
  480.                 else {
  481.                     while (target && target.nextSibling)
  482.                     {
  483.                         target = target.nextSibling.nextSibling;
  484.                         if (aFindAny || !target[cProp]) return target;
  485.                     }
  486.  
  487.                     target = aBox;
  488.                     while (target && target.previousSibling)
  489.                     {
  490.                         target = target.previousSibling.previousSibling;
  491.                         if (aFindAny || !target[cProp]) return target;
  492.                     }
  493.                 }
  494.  
  495.                 var appcontent = document.getElementById('appcontent');
  496.  
  497.                 target = aBox;
  498.                 var orientBox;
  499.                 do {
  500.                     target = target.parentNode;
  501.  
  502.                     orientBox = (target.localName == 'subbrowser-container') ? (target.previousSibling || target.nextSibling || target.parentNode) : target ;
  503.                     if (orientBox.localName == 'splitter') {
  504.                         if (orientBox.getAttribute('orient') != aOrient)
  505.                             continue;
  506.                         else
  507.                             break;
  508.                     }
  509.                     else {
  510.                         if (window.getComputedStyle(orientBox, '').getPropertyValue('-moz-box-orient') != aOrient)
  511.                             continue;
  512.                         else
  513.                             break;
  514.                     }
  515.                 }
  516.                 while (target != appcontent);
  517.  
  518.                 if (target == appcontent)
  519.                     return null;
  520.                 else
  521.                     return this.findSideBox(target, aDir, aOrient);
  522.             ]]></body>
  523.         </method>
  524.  
  525.  
  526.         <method name="toggleSyncScroll">
  527.             <body><![CDATA[
  528.                 this.syncScroll = !this.syncScroll;
  529.                 if (this.syncScroll) {
  530.                     var subbrowser = this;
  531.                     if (SplitBrowser.mainBrowserBox.syncScroll)
  532.                         subbrowser = SplitBrowser.mainBrowserBox;
  533.                     subbrowser.notifyScroll(subbrowser.browser.contentWindow);
  534.                 }
  535.             ]]></body>
  536.         </method>
  537.         <property name="syncScroll"
  538.             onget="return this.getAttribute('sync-scroll') == 'true';"
  539.             onset="if (val) this.setAttribute('sync-scroll', true); else this.removeAttribute('sync-scroll'); return val ? true : false ;"/>
  540.         <method name="onContentScroll">
  541.             <parameter name="aEvent"/>
  542.             <body><![CDATA[
  543.                 if (!this.syncScroll ||
  544.                     this.scrollSynchronizing ||
  545.                     !(aEvent.originalTarget instanceof Document)) return;
  546.                 this.notifyScroll(aEvent.originalTarget.defaultView);
  547.             ]]></body>
  548.         </method>
  549.         <method name="notifyScroll">
  550.             <parameter name="aFrame"/>
  551.             <body><![CDATA[
  552.                 // ignore background tabs
  553.                 if (aFrame.top != this.browser.contentWindow) return;
  554.                 var info = {
  555.                         x    : aFrame.scrollX,
  556.                         maxX : aFrame.scrollMaxX,
  557.                         y    : aFrame.scrollY,
  558.                         maxY : aFrame.scrollMaxY
  559.                     };
  560.                 var os = Components.classes['@mozilla.org/observer-service;1']
  561.                             .getService(Components.interfaces.nsIObserverService);
  562.                 os.notifyObservers(aFrame, 'subbrowser:syncScroll', info.toSource());
  563.             ]]></body>
  564.         </method>
  565.         <field name="syncScrollObserver"><![CDATA[
  566.         ({
  567.             mOwner : this,
  568.             observe: function(aSubject, aTopic, aData)
  569.             {
  570.                 if (!this.mOwner.syncScroll) return;
  571.  
  572.                 // in other windows
  573.                 if (aSubject.top
  574.                     .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
  575.                     .getInterface(Components.interfaces.nsIWebNavigation)
  576.                     .QueryInterface(Components.interfaces.nsIDocShell)
  577.                     .QueryInterface(Components.interfaces.nsIDocShellTreeItem)
  578.                     .parent
  579.                     .QueryInterface(Components.interfaces.nsIDocShell)
  580.                     .QueryInterface(Components.interfaces.nsIWebNavigation)
  581.                     .document.defaultView != window) return;
  582.  
  583.                 var w = this.mOwner.browser.contentWindow;
  584.                 if (aSubject.top == w) return;
  585.  
  586.                 var info = SplitBrowser.evalInSandbox('('+aData+')');
  587.                 this.mOwner.scrollSynchronizing = true;
  588.                 w.scrollTo(
  589.                     (
  590.                         SplitBrowser.getPref('splitbrowser.syncScroll.horizontal') ?
  591.                             (info.x / info.maxX * w.scrollMaxX) : w.scrollX
  592.                     ),
  593.                     (
  594.                         SplitBrowser.getPref('splitbrowser.syncScroll.vertical') ?
  595.                             (info.y / info.maxY * w.scrollMaxY) : w.scrollY
  596.                     )
  597.                 );
  598.                 window.setTimeout(function(aOwner) {
  599.                     aOwner.scrollSynchronizing = false;
  600.                 }, 0, this.mOwner);
  601.             }
  602.         })
  603.         ]]></field>
  604.  
  605.  
  606.         <property name="name"
  607.             onget="return this.getAttribute('name') || '';"
  608.             onset="this.setAttribute('name', val); return val;"/>
  609.  
  610.  
  611.  
  612.         <method name="checkEventFiredOnEdge">
  613.             <parameter name="aEvent"/>
  614.             <body><![CDATA[
  615.                 if (this.contentCollapsed) {
  616.                     return {
  617.                         onTopEdge    : false,
  618.                         onBottomEdge : false,
  619.                         onLeftEdge   : false,
  620.                         onRightEdge  : false,
  621.                         inTopArea    : false,
  622.                         inBottomArea : false,
  623.                         inLeftArea   : false,
  624.                         inRightArea  : false
  625.                     };
  626.                 }
  627.  
  628.                 var offset = SplitBrowser.addButtonSize;
  629.                 var box    = this.contentAreaSizeObject;
  630.                 if (!box) return null;
  631.  
  632.                 var isTop    = (aEvent.screenY >= box.screenY &&
  633.                                 aEvent.screenY < box.screenY+offset &&
  634.                                 aEvent.screenX >= box.areaScreenX &&
  635.                                 aEvent.screenX < box.areaScreenX+box.areaWidth);
  636.                 var isBottom = (aEvent.screenY <= box.screenY+box.height &&
  637.                                 aEvent.screenY > box.screenY+box.height-offset &&
  638.                                 aEvent.screenX >= box.areaScreenX &&
  639.                                 aEvent.screenX < box.areaScreenX+box.areaWidth);
  640.                 var isLeft   = (aEvent.screenX >= box.screenX &&
  641.                                 aEvent.screenX < box.screenX+offset &&
  642.                                 aEvent.screenY >= box.areaScreenY &&
  643.                                 aEvent.screenY < box.areaScreenY+box.areaHeight);
  644.                 var isRight  = (aEvent.screenX <= box.screenX+box.width &&
  645.                                 aEvent.screenX > box.screenX+box.width-offset &&
  646.                                 aEvent.screenY >= box.areaScreenY &&
  647.                                 aEvent.screenY < box.areaScreenY+box.areaHeight);
  648.  
  649.                 var pos = SplitBrowser.getDropPositionOnContentArea(aEvent, box.box);
  650.                 return {
  651.                     onTopEdge    : isTop,
  652.                     onBottomEdge : isBottom,
  653.                     onLeftEdge   : isLeft,
  654.                     onRightEdge  : isRight,
  655.                     inTopArea    : pos == SplitBrowser.POSITION_TOP,
  656.                     inBottomArea : pos == SplitBrowser.POSITION_BOTTOM,
  657.                     inLeftArea   : pos == SplitBrowser.POSITION_LEFT,
  658.                     inRightArea  : pos == SplitBrowser.POSITION_RIGHT
  659.                 };
  660.             ]]></body>
  661.         </method>
  662.  
  663.         <method name="handleMouseOverEvent">
  664.             <parameter name="aEvent"/>
  665.             <parameter name="aModifierPressed"/>
  666.             <body><![CDATA[
  667.                 var check = this.checkEventFiredOnEdge(aEvent);
  668.                 if (!check) return;
  669.  
  670.                 var isTop, isBottom, isRight, isLeft;
  671.                 if (aEvent.type.indexOf('drag') < 0) { // mousemove
  672.                     isTop    = check.onTopEdge;
  673.                     isBottom = check.onBottomEdge;
  674.                     isLeft   = check.onLeftEdge;
  675.                     isRight  = check.onRightEdge;
  676.                 }
  677.                 else { // drag***
  678.                     isTop    = check.inTopArea;
  679.                     isBottom = check.inBottomArea;
  680.                     isLeft   = check.inLeftArea;
  681.                     isRight  = check.inRightArea;
  682.                 }
  683.                 if (isTop || isBottom || isLeft || isRight) {
  684.                     var isFirstEnter = false;
  685.                     if (
  686.                         (isTop && !this.mIsMouseOverTop) ||
  687.                         (isBottom && !this.mIsMouseOverBottom) ||
  688.                         (isLeft && !this.mIsMouseOverLeft) ||
  689.                         (isRight && !this.mIsMouseOverRight)
  690.                         ) {
  691.                         this.mIsMouseOverTop    = isTop;
  692.                         this.mIsMouseOverBottom = isBottom;
  693.                         this.mIsMouseOverLeft   = isLeft;
  694.                         this.mIsMouseOverRight  = isRight;
  695.                         isFirstEnter = true;
  696.                     }
  697.                     var newEvent = document.createEvent('Events');
  698.                     newEvent.initEvent(
  699.                         (isFirstEnter ?
  700.                             'SubBrowserEnterContentAreaEdge' :
  701.                             'SubBrowserHoverContentAreaEdge'
  702.                         ),
  703.                         false,
  704.                         true
  705.                     );
  706.                     newEvent.isTop    = isTop;
  707.                     newEvent.isBottom = isBottom;
  708.                     newEvent.isLeft   = isLeft;
  709.                     newEvent.isRight  = isRight;
  710.                     newEvent.targetSubBrowser = this;
  711.                     newEvent.modifierKeyPressed = aModifierPressed;
  712.                     newEvent.firedBy = aEvent.type;
  713.                     newEvent.clientX = aEvent.clientX;
  714.                     newEvent.clientY = aEvent.clientY;
  715.                     newEvent.screenX = aEvent.screenX;
  716.                     newEvent.screenY = aEvent.screenY;
  717.                     this.dispatchEvent(newEvent);
  718.                 }
  719.                 else if (
  720.                     this.mIsMouseOverTop ||
  721.                     this.mIsMouseOverBottom ||
  722.                     this.mIsMouseOverLeft ||
  723.                     this.mIsMouseOverRight
  724.                     ) {
  725.                     this.mIsMouseOverTop    = false;
  726.                     this.mIsMouseOverBottom = false;
  727.                     this.mIsMouseOverLeft   = false;
  728.                     this.mIsMouseOverRight  = false;
  729.  
  730.                     var newEvent = document.createEvent('Events');
  731.                     newEvent.initEvent('SubBrowserExitContentAreaEdge', false, true);
  732.                     this.dispatchEvent(newEvent);
  733.                 }
  734.             ]]></body>
  735.         </method>
  736.  
  737.         <method name="handleDragOverEvent">
  738.             <parameter name="aEvent"/>
  739.             <body><![CDATA[
  740.                 const DragService = Components.classes['@mozilla.org/widget/dragservice;1'].getService(Components.interfaces.nsIDragService);
  741.                 var session = DragService.getCurrentSession();
  742.                 if (!session) return;
  743.  
  744.                 var isSubBrowser = session.isDataFlavorSupported('application/x-moz-splitbrowser');
  745.                 if (isSubBrowser ||
  746.                     session.isDataFlavorSupported('application/x-moz-tabbrowser-tab') ||
  747.                     session.isDataFlavorSupported('text/x-moz-url') ||
  748.                     session.isDataFlavorSupported('text/unicode') ||
  749.                     session.isDataFlavorSupported('application/x-moz-file')) {
  750.                     this.handleMouseOverEvent(aEvent);
  751.                     var check = this.checkEventFiredOnEdge(aEvent);
  752.                     if (!check) return;
  753.                     if (
  754.                         SplitBrowser.isLinux &&
  755.                         SplitBrowser.addButton.targetSubBrowser == this &&
  756.                         (
  757.                             check.inTopArea ||
  758.                             check.inBottomArea ||
  759.                             check.inLeftArea ||
  760.                             check.inRightArea
  761.                         )
  762.                         ) {
  763.                         session.canDrop = true;
  764.                         aEvent.stopPropagation();
  765.                     }
  766.                 }
  767.             ]]></body>
  768.         </method>
  769.  
  770.  
  771.         <property name="focused">
  772.             <setter><![CDATA[
  773.                 if (this.contentCollapsed)
  774.                     val = false;
  775.  
  776.                 var b = this.browser;
  777.                 if (b && b.localName == 'tabbrowser')
  778.                     b = b.mCurrentBrowser;
  779.  
  780.                 if (val || !SplitBrowser.browsers.length) {
  781.                     this.setAttribute('subbrowser-focused', true);
  782.                     if (b) {
  783.                         b.removeAttribute('type');
  784.                         b.setAttribute('type', 'content-primary');
  785.                     }
  786.                 }
  787.                 else if (SplitBrowser.browsers.length) {
  788.                     this.removeAttribute('subbrowser-focused');
  789.                     if (b) {
  790.                         b.removeAttribute('type');
  791.                         b.setAttribute('type', 'content');
  792.                     }
  793.                 }
  794.                 return val;
  795.             ]]></setter>
  796.             <getter><![CDATA[
  797.                 return this.getAttribute('subbrowser-focused') == 'true';
  798.             ]]></getter>
  799.         </property>
  800.  
  801.         <method name="focus">
  802.             <body><![CDATA[
  803.                 if (SplitBrowser.activeSubBrowser != this)
  804.                     SplitBrowser.activeSubBrowser = this;
  805.                 this.focused = true;
  806.             ]]></body>
  807.         </method>
  808.         <method name="blur">
  809.             <body><![CDATA[
  810.                 if (SplitBrowser.activeSubBrowser == this)
  811.                     SplitBrowser.activeSubBrowser = null;
  812.                 this.focused = false;
  813.                 this.isUrlbarFocused = false;
  814.             ]]></body>
  815.         </method>
  816.  
  817.         <method name="autoFocus">
  818.             <body><![CDATA[
  819.                 var delay = SplitBrowser.subBrowserAutoFocusDelay;
  820.                 if (
  821.                     this.focused ||
  822.                     this.mAutoFocusTimer ||
  823.                     delay < 0
  824.                     )
  825.                     return;
  826.  
  827.                 this.mAutoFocusTimer = window.setTimeout(
  828.                     function(aThis) {
  829.                         aThis.focus();
  830.                         aThis.cancelAutoFocus();
  831.                     },
  832.                     delay,
  833.                     this
  834.                 );
  835.             ]]></body>
  836.         </method>
  837.         <method name="cancelAutoFocus">
  838.             <body><![CDATA[
  839.                 if (this.mAutoFocusTimer) {
  840.                     window.clearInterval(this.mAutoFocusTimer);
  841.                     this.mAutoFocusTimer = null;
  842.                 }
  843.             ]]></body>
  844.         </method>
  845.         <field name="mAutoFocusTimer">null</field>
  846.  
  847.     </implementation>
  848.  
  849.     <handlers>
  850.         <handler event="mousemove"
  851.             action="var type = SplitBrowser.getPref('splitbrowser.show.addbuttons.hover.type'); var isModifier = type == 1 && SplitBrowser.modifierKeyPressed; if (type == 0 || isModifier) this.handleMouseOverEvent(event, isModifier); return true;"/>
  852.         <handler event="dragover" phase="capturing"
  853.             action="if (SplitBrowser.getPref('splitbrowser.show.addbuttons.dragdrop')) this.handleDragOverEvent(event); return true;"/>
  854.  
  855.         <handler event="focus" phase="capturing"
  856.             action="this.focus();"/>
  857.  
  858.         <handler event="scroll" phase="capturing"
  859.             action="this.onContentScroll(event);"/>
  860.  
  861.         <handler event="mouseover"
  862.             action="window.setTimeout(function(aThis) { if (aThis.autoFocus) aThis.autoFocus(); }, 0, this);"/>
  863.         <handler event="mouseout"
  864.             action="this.cancelAutoFocus();"/>
  865.     </handlers>
  866. </binding>
  867.  
  868. <binding id="subbrowser-primary" extends="#subbrowser-base">
  869.     <implementation>
  870.         <property name="vContentCollapsed" readonly="true"
  871.             onget="return this.boxObject.width == 0;"/>
  872.         <property name="hContentCollapsed" readonly="true"
  873.             onget="return this.boxObject.height == 0;"/>
  874.         <property name="vContentCompletelyCollapsed" readonly="true"
  875.             onget="return this.vContentCollapsed"/>
  876.         <property name="hContentCompletelyCollapsed" readonly="true"
  877.             onget="return this.hContentCollapsed"/>
  878.         <property name="browser" readonly="true"
  879.             onget="return gBrowser;"/>
  880.  
  881.         <property name="syncScroll"
  882.             onget="return SplitBrowser.getPref('splitbrowser.syncScroll.mainArea');"
  883.             onset="SplitBrowser.setPref('splitbrowser.syncScroll.mainArea', val ? true : false ); return val ? true : false ;"/>
  884.  
  885.         <constructor><![CDATA[
  886.             var os = Components.classes['@mozilla.org/observer-service;1']
  887.                         .getService(Components.interfaces.nsIObserverService);
  888.             os.addObserver(this.syncScrollObserver, 'subbrowser:syncScroll', false);
  889.         ]]></constructor>
  890.         <destructor><![CDATA[
  891.             var os = Components.classes['@mozilla.org/observer-service;1']
  892.                         .getService(Components.interfaces.nsIObserverService);
  893.             os.removeObserver(this.syncScrollObserver, 'subbrowser:syncScroll');
  894.         ]]></destructor>
  895.     </implementation>
  896. </binding>
  897.  
  898. <binding id="subbrowser" extends="#subbrowser-base">
  899.     <content orient="vertical"
  900.         context="_child">
  901.         <xul:menupopup anonid="contextmenu"
  902.             onpopupshowing="
  903.                 SplitBrowser.getSubBrowserFromChild(this).resetNavigation();
  904.                 SplitBrowser.getSubBrowserFromChild(this).updateContextMenu(event);
  905.             "
  906.             oncommand="SplitBrowser.getSubBrowserFromChild(this).resetNavigation();"
  907.             ondraggesture="event.stopPropagation();">
  908.             <xul:menuitem class="subbrowser-context-close"
  909.                 label="&splitbrowser.subbrowser.menu.close;"
  910.                 oncommand="SplitBrowser.getSubBrowserFromChild(this).close();"/>
  911.             <xul:menuitem class="subbrowser-context-collapse"
  912.                 label="&splitbrowser.subbrowser.menu.collapse;"
  913.                 oncommand="SplitBrowser.getSubBrowserFromChild(this).collapse();"/>
  914.             <xul:menuitem class="subbrowser-context-expand"
  915.                 label="&splitbrowser.subbrowser.menu.expand;"
  916.                 oncommand="SplitBrowser.getSubBrowserFromChild(this).expand();"/>
  917.             <xul:menuseparator/>
  918.             <xul:menuitem class="subbrowser-context-openNewTab"
  919.                 label="&splitbrowser.subbrowser.menu.openNewTab;"
  920.                 oncommand="SplitBrowser.getSubBrowserFromChild(this).openNewTab();"/>
  921.             <xul:menuseparator/>
  922.             <xul:menuitem class="subbrowser-context-syncScroll"
  923.                 label="&splitbrowser.subbrowser.menu.syncScroll;"
  924.                 type="checkbox"
  925.                 autocheck="false"
  926.                 oncommand="SplitBrowser.getSubBrowserFromChild(this).toggleSyncScroll();"/>
  927.         </xul:menupopup>
  928.         <xul:hbox flex="1" class="subbrowser-content">
  929.             <xul:toolbox anonid="subbrowser-toolbox-vertical"
  930.                 orient="vertical"
  931.                 class="subbrowser-toolbox subbrowser-toolbox-vertical">
  932.             <xul:toolbar anonid="subbrowser-toolbar-vertical"
  933.                 orient="vertical"
  934.                 flex="1"
  935.                 class="subbrowser-toolbar subbrowser-toolbar-vertical"
  936.                 align="center"
  937.                  ondraggesture="
  938.                      SplitBrowser.getSubBrowserFromChild(this).resetNavigation();
  939.                      nsDragAndDrop.startDrag(event, SplitBrowser.getSubBrowserFromChild(this).pageDNDObserver);
  940.                  "
  941.                 ondragdrop="nsDragAndDrop.drop(event, SplitBrowser.getSubBrowserFromChild(this).pageDNDObserver);"
  942.                 ondragover="nsDragAndDrop.dragOver(event, SplitBrowser.getSubBrowserFromChild(this).pageDNDObserver);"
  943.                 onclick="if (event.button == 1) SplitBrowser.getSubBrowserFromChild(this).toggleCollapsed();"
  944.                 ondblclick="SplitBrowser.getSubBrowserFromChild(this).toggleCollapsed();">
  945.                 <xul:toolbarbutton
  946.                     anonid="close-button-vertical"
  947.                     class="tabs-closebutton toolbarbutton-1"
  948.                     tooltiptext="&splitbrowser.subbrowser.close.tooltip;"
  949.                     oncommand="SplitBrowser.getSubBrowserFromChild(this).close();"
  950.                     ondblclick="event.stopPropagation();"/>
  951.                 <xul:toolbarbutton
  952.                     anonid="collapse-button-vertical"
  953.                     tooltiptext="&splitbrowser.subbrowser.collapse.tooltip;"
  954.                     oncommand="SplitBrowser.getSubBrowserFromChild(this).collapse();"
  955.                     ondblclick="event.stopPropagation();"
  956.                     class="subbrowser-toolbar-item button collapse"/>
  957.                 <xul:toolbarbutton
  958.                     anonid="expand-button-vertical"
  959.                     tooltiptext="&splitbrowser.subbrowser.expand.tooltip;"
  960.                     oncommand="SplitBrowser.getSubBrowserFromChild(this).expand();"
  961.                     ondblclick="event.stopPropagation();"
  962.                     class="subbrowser-toolbar-item button expand"/>
  963.                 <xul:toolbarbutton
  964.                     anonid="syncScroll-button-vertical"
  965.                     tooltiptext="&splitbrowser.subbrowser.syncScroll.tooltip;"
  966.                     oncommand="SplitBrowser.getSubBrowserFromChild(this).toggleSyncScroll();"
  967.                     ondblclick="event.stopPropagation();"
  968.                     class="subbrowser-toolbar-item button syncScroll"
  969.                     type="checkbox"
  970.                     autoCheck="false"
  971.                     xbl:inherits="checked=sync-scroll"/>
  972.                 <xul:box class="subbrowser-toolbar-item favicon-box">
  973.                     <xul:image class="subbrowser-toolbar-item favicon"
  974.                         anonid="vertical-favicon"
  975.                         validate="never"
  976.                         onerror="SplitBrowser.getSubBrowserFromChild(this).addToMissedIconCache(this.getAttribute('src')); this.removeAttribute('src');"/>
  977.                 </xul:box>
  978.                 <xul:description anonid="vertical-title"
  979.                     class="subbrowser-title subbrowser-vertical-title"
  980.                     flex="1"/>
  981.             </xul:toolbar>
  982.             </xul:toolbox>
  983.             <xul:vbox flex="1">
  984.                 <xul:toolbox anonid="subbrowser-toolbox-horizontal"
  985.                     orient="horizontal"
  986.                     class="subbrowser-toolbox subbrowser-toolbox-horizontal">
  987.                 <xul:toolbar anonid="subbrowser-toolbar-horizontal"
  988.                     class="subbrowser-toolbar subbrowser-toolbar-horizontal"
  989.                     align="center"
  990.                     flex="1"
  991.                      ondraggesture="
  992.                          SplitBrowser.getSubBrowserFromChild(this).resetNavigation();
  993.                          nsDragAndDrop.startDrag(event, SplitBrowser.getSubBrowserFromChild(this).pageDNDObserver);
  994.                      "
  995.                     ondragdrop="nsDragAndDrop.drop(event, SplitBrowser.getSubBrowserFromChild(this).pageDNDObserver);"
  996.                     ondragover="nsDragAndDrop.dragOver(event, SplitBrowser.getSubBrowserFromChild(this).pageDNDObserver);"
  997.                      onclick="
  998.                          if (event.button == 0 &&
  999.                              this.firstChild.getAttribute('selectedIndex') == '0')
  1000.                             SplitBrowser.getSubBrowserFromChild(this).resetNavigation();
  1001.                          if (event.button == 1)
  1002.                              SplitBrowser.getSubBrowserFromChild(this).toggleCollapsed();
  1003.                      "
  1004.                     ondblclick="SplitBrowser.getSubBrowserFromChild(this).toggleCollapsed();">
  1005.                     <xul:toolbarbutton
  1006.                         anonid="syncScroll-button-horizontal"
  1007.                         tooltiptext="&splitbrowser.subbrowser.syncScroll.tooltip;"
  1008.                         oncommand="SplitBrowser.getSubBrowserFromChild(this).toggleSyncScroll();"
  1009.                         ondblclick="event.stopPropagation();"
  1010.                         class="subbrowser-toolbar-item button syncScroll"
  1011.                         type="checkbox"
  1012.                         autoCheck="false"
  1013.                         xbl:inherits="checked=sync-scroll"/>
  1014.                     <xul:stack anonid="toolbar-deck"
  1015.                         flex="1"
  1016.                         onmouseover="SplitBrowser.getSubBrowserFromChild(this).toggleNavigationOnHover(true);"
  1017.                         onmouseout="SplitBrowser.getSubBrowserFromChild(this).toggleNavigationOnHover(false);"
  1018.                         selectedIndex="0">
  1019.                         <xul:hbox class="subbrowser-toolbar-content" flex="1" align="center"
  1020.                             anonid="toolbar-deck-titlebar">
  1021.                             <xul:box class="subbrowser-toolbar-item favicon-box">
  1022.                                 <xul:image class="subbrowser-toolbar-item favicon"
  1023.                                     anonid="favicon"
  1024.                                     validate="never"
  1025.                                     ondraggesture="nsDragAndDrop.startDrag(event, SplitBrowser.getSubBrowserFromChild(this).pageDNDObserver);"
  1026.                                     onerror="SplitBrowser.getSubBrowserFromChild(this).addToMissedIconCache(this.getAttribute('src')); this.removeAttribute('src');"/>
  1027.                             </xul:box>
  1028.                             <xul:stack flex="1">
  1029.                                 <xul:progressmeter class="subbrowser-toolbar-item progress"
  1030.                                     anonid="progressmeter"
  1031.                                     collapsed="true"
  1032.                                     flex="1"/>
  1033.                                 <xul:label anonid="title"
  1034.                                     class="subbrowser-title"
  1035.                                     blank-label="&splitbrowser.subbrowser.blank;"
  1036.                                     loading-label="&splitbrowser.subbrowser.loading;"
  1037.                                     flex="1"
  1038.                                     crop="end"/>
  1039.                             </xul:stack>
  1040.                         </xul:hbox>
  1041.                         <xul:hbox class="subbrowser-toolbar-content" flex="1" align="center"
  1042.                             anonid="toolbar-deck-navbar">
  1043.                             <xul:toolbarbutton
  1044.                                 anonid="back-button"
  1045.                                 tooltiptext="&splitbrowser.subbrowser.goBack.tooltip;"
  1046.                                 oncommand="SplitBrowser.getSubBrowserFromChild(this).goBack();"
  1047.                                 ondblclick="event.stopPropagation();"
  1048.                                 class="subbrowser-toolbar-item button goBack"
  1049.                                 disabled="true"/>
  1050.                             <xul:toolbarbutton
  1051.                                 anonid="forward-button"
  1052.                                 tooltiptext="&splitbrowser.subbrowser.goForward.tooltip;"
  1053.                                 oncommand="SplitBrowser.getSubBrowserFromChild(this).goForward();"
  1054.                                 ondblclick="event.stopPropagation();"
  1055.                                 class="subbrowser-toolbar-item button goForward"
  1056.                                 disabled="true"/>
  1057.                             <xul:toolbarbutton
  1058.                                 anonid="reload-button"
  1059.                                 tooltiptext="&splitbrowser.subbrowser.reload.tooltip;"
  1060.                                 oncommand="SplitBrowser.getSubBrowserFromChild(this).reload(event.shiftKey);"
  1061.                                 ondblclick="event.stopPropagation();"
  1062.                                 class="subbrowser-toolbar-item button reload"
  1063.                                 disabled="true"/>
  1064.                             <xul:toolbarbutton
  1065.                                 anonid="stop-button"
  1066.                                 tooltiptext="&splitbrowser.subbrowser.stop.tooltip;"
  1067.                                 oncommand="SplitBrowser.getSubBrowserFromChild(this).stop();"
  1068.                                 ondblclick="event.stopPropagation();"
  1069.                                 class="subbrowser-toolbar-item button stop"
  1070.                                 disabled="true"/>
  1071.                             <xul:hbox class="subbrowser-toolbar-item urlbar-box"
  1072.                                 align="center"
  1073.                                 flex="1">
  1074.                                 <xul:stack flex="1">
  1075.                                     <xul:progressmeter class="subbrowser-toolbar-item urlbar-progress"
  1076.                                         anonid="urlbar-progressmeter"
  1077.                                         collapsed="true"
  1078.                                         flex="1"/>
  1079.                                     <xul:textbox flex="1"
  1080.                                         anonid="urlbar"
  1081.                                         class="subbrowser-toolbar-item urlbar-textbox"
  1082.                                         ontextentered="SplitBrowser.getSubBrowserFromChild(this).load(this.value);"
  1083.                                         ontextreverted="SplitBrowser.getSubBrowserFromChild(this).load(this.value);"
  1084.                                         onfocus="SplitBrowser.getSubBrowserFromChild(this).isUrlbarFocused = true;"
  1085.                                         onclick="event.stopPropagation();"
  1086.                                         ondblclick="event.stopPropagation();"
  1087.                                         sizetopopup="pref"
  1088.                                         clickSelectsAll="true"
  1089.                                         type="autocomplete"
  1090.                                         autocompletesearch="history"
  1091.                                         autocompletepopup="PopupAutoComplete"
  1092.                                         completeselectedindex="true"
  1093.                                         tabscrolling="true"
  1094.                                         showcommentcolumn="true"
  1095.                                         enablehistory="true">
  1096.                                         <xul:box class="subbrowser-toolbar-item urlbar-favicon-box">
  1097.                                             <xul:image class="subbrowser-toolbar-item urlbar-favicon"
  1098.                                                 anonid="urlbar-favicon"
  1099.                                                 validate="never"
  1100.                                                 onerror="SplitBrowser.getSubBrowserFromChild(this).addToMissedIconCache(this.getAttribute('src')); this.removeAttribute('src');"/>
  1101.                                         </xul:box>
  1102.                                     </xul:textbox>
  1103.                                  </xul:stack>
  1104.                             </xul:hbox>
  1105.                             <xul:toolbarbutton
  1106.                                 anonid="go-button"
  1107.                                 class="subbrowser-toolbar-item go"
  1108.                                 label="&splitbrowser.subbrowser.go.label;"
  1109.                                 tooltiptext="&splitbrowser.subbrowser.go.tooltip;"
  1110.                                 oncommand="SplitBrowser.getSubBrowserFromChild(this).go();"
  1111.                                 ondblclick="event.stopPropagation();"/>
  1112.                         </xul:hbox>
  1113.                     </xul:stack>
  1114.                     <xul:toolbarbutton
  1115.                         anonid="collapse-button"
  1116.                         tooltiptext="&splitbrowser.subbrowser.collapse.tooltip;"
  1117.                         oncommand="SplitBrowser.getSubBrowserFromChild(this).collapse();"
  1118.                         ondblclick="event.stopPropagation();"
  1119.                         class="subbrowser-toolbar-item button collapse"/>
  1120.                     <xul:toolbarbutton
  1121.                         anonid="expand-button"
  1122.                         tooltiptext="&splitbrowser.subbrowser.expand.tooltip;"
  1123.                         oncommand="SplitBrowser.getSubBrowserFromChild(this).expand();"
  1124.                         ondblclick="event.stopPropagation();"
  1125.                         class="subbrowser-toolbar-item button expand"/>
  1126.                     <xul:toolbarbutton
  1127.                         anonid="close-button"
  1128.                         class="tabs-closebutton toolbarbutton-1"
  1129.                         tooltiptext="&splitbrowser.subbrowser.close.tooltip;"
  1130.                         oncommand="SplitBrowser.getSubBrowserFromChild(this).close();"
  1131.                         ondblclick="event.stopPropagation();"/>
  1132.                 </xul:toolbar>
  1133.                 </xul:toolbox>
  1134.                 <xul:hbox class="subbrowser-browser-box"
  1135.                     flex="1"
  1136.                     onkeypress="if ('findBar_OnBrowserKeyPress' in window) findBar_OnBrowserKeyPress(event);"
  1137.                     onmouseup="if ('findBar_OnBrowserMouseUp' in window) findBar_OnBrowserMouseUp(event);">
  1138.                     <xul:tabbrowser anonid="browser-tabbrowser"
  1139.                         class="subbrowser-browser"
  1140.                         flex="1"
  1141.                         type="content"
  1142.                         onnewtab="
  1143.                             var node = this;
  1144.                             while (node.localName != 'tabbrowser') {
  1145.                                 node = node.parentNode;
  1146.                             }
  1147.                             node.parentNode.openNewTab();
  1148.                         "
  1149.                         onclick="return contentAreaClick(event, SplitBrowser.fieldNormalClicks(SplitBrowser.getSubBrowserFromChild(this).name));"
  1150.                         ondragdrop="nsDragAndDrop.drop(event, SplitBrowser.getSubBrowserFromChild(this).pageDNDObserver);"
  1151.                         content="about:blank"
  1152.                         contenttooltip="aHTMLTooltip"
  1153.                         contextmenu="contentAreaContextMenu"
  1154.                         contentcontextmenu="contentAreaContextMenu"
  1155.                         autocompletepopup="PopupAutoComplete"
  1156.                         disablehistory="true"/>
  1157.                     <xul:browser anonid="browser-simple"
  1158.                         class="subbrowser-browser"
  1159.                         flex="1"
  1160.                         type="content"
  1161.                         onclick="return contentAreaClick(event, false);"
  1162.                         ondragdrop="nsDragAndDrop.drop(event, SplitBrowser.getSubBrowserFromChild(this).pageDNDObserver);"
  1163.                         content="about:blank"
  1164.                         contenttooltip="aHTMLTooltip"
  1165.                         contextmenu="contentAreaContextMenu"
  1166.                         contentcontextmenu="contentAreaContextMenu"
  1167.                         autocompletepopup="PopupAutoComplete"/>
  1168.                 </xul:hbox>
  1169.             </xul:vbox>
  1170.         </xul:hbox>
  1171.     </content>
  1172.  
  1173.     <implementation>
  1174.         <property name="toolbar" readonly="true"
  1175.             onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'subbrowser-toolbar-horizontal');"/>
  1176.  
  1177.         <property name="hToolbox" readonly="true"
  1178.             onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'subbrowser-toolbox-horizontal');"/>
  1179.         <property name="vToolbox" readonly="true"
  1180.             onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'subbrowser-toolbox-vertical');"/>
  1181.  
  1182.         <property name="toolbarDeck" readonly="true"
  1183.             onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'toolbar-deck');"/>
  1184.  
  1185.         <property name="browser" readonly="true"
  1186.             onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'browser-'+this.browserType);"/>
  1187.         <property name="browserType" readonly="true"
  1188.             onget="return this.getAttribute('browsertype') == 'simple' ? 'simple' : 'tabbrowser' ;"/>
  1189.  
  1190.         <property name="backButton" readonly="true"
  1191.             onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'back-button');"/>
  1192.         <property name="forwardButton" readonly="true"
  1193.             onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'forward-button');"/>
  1194.         <property name="reloadButton" readonly="true"
  1195.             onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'reload-button');"/>
  1196.         <property name="stopButton" readonly="true"
  1197.             onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'stop-button');"/>
  1198.         <property name="urlbar" readonly="true"
  1199.             onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'urlbar');"/>
  1200.         <property name="title" readonly="true"
  1201.             onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'title');"/>
  1202.         <property name="vTitle" readonly="true"
  1203.             onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'vertical-title');"/>
  1204.         <property name="favicon" readonly="true"
  1205.             onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'favicon');"/>
  1206.         <property name="vFavicon" readonly="true"
  1207.             onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'vertical-favicon');"/>
  1208.         <property name="urlbarFavicon" readonly="true"
  1209.             onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'urlbar-favicon');"/>
  1210.         <property name="progressmeter" readonly="true"
  1211.             onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'progressmeter');"/>
  1212.         <property name="urlbarProgressmeter" readonly="true"
  1213.             onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'urlbar-progressmeter');"/>
  1214.         <property name="goButton" readonly="true"
  1215.             onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'go-button');"/>
  1216.         <property name="contextmenu" readonly="true"
  1217.             onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'contextmenu');"/>
  1218.  
  1219.         <property name="src"
  1220.             onset="this.setAttribute('src', val); this.load(val); return val;"
  1221.             onget="return this.getAttribute('src') || 'about:blank';"/>
  1222.         <property name="contentWindow"
  1223.             readonly="true"
  1224.             onget="return this.browser.contentWindow;"/>
  1225.  
  1226.  
  1227.         <property name="isIeTab" readonly="true"
  1228.             onget="return ('IeTab' in window && this.browser.currentURI.spec.indexOf(gIeTabChromeStr) == 0);"/>
  1229.         <method name="getIeTabOf">
  1230.             <parameter name="aBrowser"/>
  1231.             <body><![CDATA[
  1232.                 if (!('IeTab' in window)) return null;
  1233.                 if (
  1234.                     aBrowser &&
  1235.                     aBrowser.currentURI &&
  1236.                     gIeTab.startsWith(aBrowser.currentURI.spec, gIeTabChromeStr)
  1237.                     ) {
  1238.                     if (aBrowser.contentDocument &&
  1239.                         aBrowser.contentDocument.getElementById('IETab')) {
  1240.                         var obj = aBrowser.contentDocument.getElementById('IETab');
  1241.                         return (obj.wrappedJSObject ? obj.wrappedJSObject : obj );
  1242.                     }
  1243.                 }
  1244.                 return null;
  1245.             ]]></body>
  1246.         </method>
  1247.  
  1248.  
  1249.         <method name="load">
  1250.             <parameter name="aURI"/>
  1251.             <body><![CDATA[
  1252.                 if (!aURI) aURI = 'about:blank';
  1253.                 this.browser.loadURI(aURI);
  1254.                 this.setAttribute('src', aURI);
  1255.             ]]></body>
  1256.         </method>
  1257.  
  1258.         <method name="goBack">
  1259.             <body><![CDATA[
  1260.                 if (this.browser.canGoBack) {
  1261.                     this.browser.goBack();
  1262.                 }
  1263.             ]]></body>
  1264.         </method>
  1265.         <method name="goForward">
  1266.             <body><![CDATA[
  1267.                 if (this.browser.canGoForward) {
  1268.                     this.browser.goForward();
  1269.                 }
  1270.             ]]></body>
  1271.         </method>
  1272.         <method name="reload">
  1273.             <parameter name="aBypassCache"/>
  1274.             <body><![CDATA[
  1275.                 if (aBypassCache) {
  1276.                     var webNav = this.browser.webNavigation;
  1277.                     try {
  1278.                         var sh = webNav.sessionHistory;
  1279.                         if (sh)
  1280.                             webNav = sh.QueryInterface(Components.interfaces.nsIWebNavigation);
  1281.                     }
  1282.                     catch(e) {
  1283.                     }
  1284.                     const reloadFlags = webNav.LOAD_FLAGS_BYPASS_PROXY | webNav.LOAD_FLAGS_BYPASS_CACHE;
  1285.                     try {
  1286.                         webNav.reload(reloadFlags);
  1287.                     }
  1288.                     catch(e) {
  1289.                     }
  1290.                 }
  1291.                 else
  1292.                     this.browser.reload();
  1293.             ]]></body>
  1294.         </method>
  1295.         <method name="stop">
  1296.             <body><![CDATA[
  1297.                 this.browser.stop();
  1298.             ]]></body>
  1299.         </method>
  1300.  
  1301.         <method name="go">
  1302.             <body><![CDATA[
  1303.                 this.load(this.urlbar.value);
  1304.             ]]></body>
  1305.         </method>
  1306.  
  1307.         <method name="close">
  1308.             <parameter name="aPreventRestore"/>
  1309.             <body><![CDATA[
  1310.                 var event = document.createEvent('Events');
  1311.                 event.initEvent('SubBrowserRemoveRequest', false, true);
  1312.                 event.canRestore = !aPreventRestore;
  1313.                 this.dispatchEvent(event);
  1314.             ]]></body>
  1315.         </method>
  1316.  
  1317.  
  1318.         <property name="minSize" readonly="true">
  1319.             <getter><![CDATA[
  1320.                 if (this.mMinSize < 0)
  1321.                     this.mMinSize = Math.max(this.vToolbox.boxObject.width, this.hToolbox.boxObject.height) * 2;
  1322.  
  1323.                 return this.mMinSize;
  1324.             ]]></getter>
  1325.         </property>
  1326.         <field name="mMinSize">
  1327.             -1
  1328.         </field>
  1329.  
  1330.         <property name="vContentCollapsed" readonly="true"
  1331.             onget="return this.boxObject.height <= this.minSize;"/>
  1332.         <property name="hContentCollapsed" readonly="true"
  1333.             onget="return this.boxObject.width <= this.minSize;"/>
  1334.         <property name="vContentCompletelyCollapsed" readonly="true"
  1335.             onget="return this.vContentCollapsed"/>
  1336.         <property name="hContentCompletelyCollapsed" readonly="true"
  1337.             onget="return this.hContentCollapsed"/>
  1338.  
  1339.         <method name="updateContextMenu">
  1340.             <parameter name="aEvent"/>
  1341.             <body><![CDATA[
  1342.                 var popup = this.contextmenu;
  1343.                 var collapsed = this.contentCollapsed;
  1344.                 popup.getElementsByAttribute('class', 'subbrowser-context-collapse')[0].hidden = collapsed;
  1345.                 popup.getElementsByAttribute('class', 'subbrowser-context-expand')[0].hidden = !collapsed;
  1346.  
  1347.                 var tabItem = popup.getElementsByAttribute('class', 'subbrowser-context-openNewTab')[0];
  1348.                 tabItem.hidden = tabItem.previousSibling.hidden = (this.browser.localName != 'tabbrowser');
  1349.  
  1350.                 var syncItem = popup.getElementsByAttribute('class', 'subbrowser-context-syncScroll')[0];
  1351.                 if (this.syncScroll)
  1352.                     syncItem.setAttribute('checked', true);
  1353.                 else
  1354.                     syncItem.removeAttribute('checked');
  1355.             ]]></body>
  1356.         </method>
  1357.  
  1358.  
  1359.  
  1360.         <method name="updateToolbarForCurrentTab">
  1361.             <parameter name="aSwitchTab"/>
  1362.             <body><![CDATA[
  1363.                 var b      = this.browser;
  1364.                 var t      = null;
  1365.                 var isBusy = this.mIsBusy;
  1366.                 var ietab  = this.getIeTabOf(this.browser);
  1367.                 if (aSwitchTab) {
  1368.                     t = b.mCurrentTab;
  1369.                     isBusy = (t.getAttribute('busy') == 'true');
  1370.                     this.mTotalProgress = t.mSubbrowserTabTotalProgress || 0 ;
  1371.                 }
  1372.  
  1373. //if (ietab)
  1374. //dump('updateToolbarForCurrentTab(ietab) / '+ietab.title+' / '+ietab.url+'\n');
  1375.  
  1376.                 if (this.mTotalProgress &&
  1377.                     this.mTotalProgress < 1) {
  1378.                     this.progressmeter.removeAttribute('collapsed');
  1379.                     this.progressmeter.setAttribute('mode', 'normal');
  1380.                     this.progressmeter.setAttribute('value', parseInt(this.mTotalProgress * 100));
  1381.  
  1382.                     this.urlbarProgressmeter.removeAttribute('collapsed');
  1383.                     this.urlbarProgressmeter.setAttribute('mode', 'normal');
  1384.                     this.urlbarProgressmeter.setAttribute('value', parseInt(this.mTotalProgress * 100));
  1385.                 }
  1386.                 else {
  1387.                     this.progressmeter.setAttribute('collapsed', true);
  1388.                     this.urlbarProgressmeter.setAttribute('collapsed', true);
  1389.                 }
  1390.  
  1391.                 if (!isBusy) {
  1392.                     this.stopButton.setAttribute('disabled', true);
  1393.                     this.reloadButton.removeAttribute('disabled');
  1394.  
  1395.                     if (t) {
  1396.                         this.setIcon(t.getAttribute('image'));
  1397.                     }
  1398.                     else if (!this.mIconURL) {
  1399.                         this.useDefaultIcon();
  1400.                     }
  1401.  
  1402.                     this.mIsBusy = false;
  1403.                     this.removeAttribute('busy');
  1404.  
  1405.                     try {
  1406.                         if (b.canGoBack)
  1407.                             this.backButton.removeAttribute('disabled');
  1408.                         else
  1409.                             this.backButton.setAttribute('disabled', true);
  1410.  
  1411.                         if (b.canGoForward)
  1412.                             this.forwardButton.removeAttribute('disabled');
  1413.                         else
  1414.                             this.forwardButton.setAttribute('disabled', true);
  1415.                     }
  1416.                     catch(e) {
  1417.                         this.backButton.setAttribute('disabled', true);
  1418.                         this.forwardButton.setAttribute('disabled', true);
  1419.                     }
  1420.  
  1421.                     var title = (ietab ? ietab.title : b.contentDocument.title ) || this.title.getAttribute('blank-label');
  1422.                     this.title.setAttribute('value', title);
  1423.                     while (this.vTitle.hasChildNodes())
  1424.                         this.vTitle.removeChild(this.vTitle.firstChild);
  1425.                     this.vTitle.appendChild(document.createTextNode(
  1426.                         title.replace(/(.)/g, '$1\n')
  1427.                             .replace(/:/g, '..')
  1428.                             .replace(/;/g, ',.')
  1429.                             .replace(/[(\[\{<\uff1c\uff08\u300c\uff5b\u3014\u300e\u3008\u300a\u3010\uff3b\u226a]/g, '\u2227')
  1430.                             .replace(/[)\]\}>\uff1e\uff09\u300d\uff5d\u3015\u300f\u3009\u300b\u3011\uff3d\u226b]/g, '\u2228')
  1431.                             .replace(/\|/g, '<->')
  1432.                             .replace(/^[-\u2015\u30fc\uff0d\uff70]$/mg, '|')
  1433.                             .replace(/<->/mg, '--')
  1434.                     ));
  1435.                     this.setAttribute('tooltiptext', title);
  1436.                     this.updateIcon();
  1437.                 }
  1438.                 else {
  1439.                     this.stopButton.removeAttribute('disabled');
  1440.                     this.reloadButton.setAttribute('disabled', true);
  1441.  
  1442.                     this.mIsBusy = true;
  1443.                     this.setAttribute('busy', true);
  1444.                     var title = this.title.getAttribute('loading-label');
  1445.                     this.title.setAttribute('value', title);
  1446.                     while (this.vTitle.hasChildNodes())
  1447.                         this.vTitle.removeChild(this.vTitle.firstChild);
  1448.                     this.vTitle.appendChild(document.createTextNode(
  1449.                         title.replace(/(.)/g, '$1\n')
  1450.                             .replace(/:/g, '..')
  1451.                             .replace(/;/g, ',.')
  1452.                             .replace(/[(\[\{<\uff1c\uff08\u300c\uff5b\u3014\u300e\u3008\u300a\u3010\uff3b\u226a]/g, '\u2227')
  1453.                             .replace(/[)\]\}>\uff1e\uff09\u300d\uff5d\u3015\u300f\u3009\u300b\u3011\uff3d\u226b]/g, '\u2228')
  1454.                             .replace(/\|/g, '<->')
  1455.                             .replace(/^[-\u2015\u30fc\uff0d\uff70]$/mg, '|')
  1456.                             .replace(/<->/mg, '--')
  1457.                     ));
  1458.                     this.setAttribute('tooltiptext', title);
  1459.                     this.updateIcon();
  1460.                 }
  1461.  
  1462.  
  1463.                 if (ietab && ietab.url) {
  1464.                     this.urlbar.value = (/^file:\/\/.*/.test(ietab.url) ? encodeURI(gIeTab.convertToUTF8(ietab.url)) : ietab.url );
  1465.                     if (this.urlbar.value.indexOf(gIeTabChromeStr) == 0)
  1466.                         this.urlbar.value = this.urlbar.value.substring(gIeTabChromeStr.length);
  1467.                 }
  1468.                 else if (aSwitchTab) {
  1469.                     this.urlbar.value = b.currentURI.spec;
  1470.                 }
  1471.  
  1472.             ]]></body>
  1473.         </method>
  1474.  
  1475.  
  1476.  
  1477.         <method name="toggleNavigation">
  1478.             <parameter name="aShow"/>
  1479.             <body><![CDATA[
  1480.                 this.toolbarDeck.setAttribute('selectedIndex', aShow ? '1' : '0' );
  1481.                 if (this.mToggleNavigationOnHoverTimer) {
  1482.                     window.clearTimeout(this.mToggleNavigationOnHoverTimer);
  1483.                     this.mToggleNavigationOnHoverTimer = null;
  1484.                 }
  1485.             ]]></body>
  1486.         </method>
  1487.  
  1488.         <method name="toggleNavigationOnHover">
  1489.             <parameter name="aShow"/>
  1490.             <parameter name="aForce"/>
  1491.             <parameter name="aDelay"/>
  1492.             <body><![CDATA[
  1493.                 if (
  1494.                     this.getAttribute('toolbar-navigation') == 'true' ||
  1495.                     (
  1496.                         this.isUrlbarFocused &&
  1497.                         !aShow
  1498.                     )
  1499.                     ) return;
  1500.  
  1501.                 if (this.contentCollapsed) aShow = false;
  1502.  
  1503.                 if (this.mIsToolbarHover == aShow) {
  1504.                     if (!aShow && this.mToggleNavigationOnHoverTimer) {
  1505.                         window.clearTimeout(this.mToggleNavigationOnHoverTimer);
  1506.                         this.mToggleNavigationOnHoverTimer = null;
  1507.                     }
  1508.                     return;
  1509.                 }
  1510.  
  1511.                 this.mIsToolbarHover = aShow;
  1512.  
  1513.                 if (aForce && aDelay === void(0)) {
  1514.                     this.toggleNavigation(aShow);
  1515.                     return;
  1516.                 }
  1517.  
  1518.                 this.mToggleNavigationOnHoverTimer = window.setTimeout(
  1519.                     function(aShowFlag, aThis) {
  1520.                         if (aShowFlag == aThis.mIsToolbarHover &&
  1521.                             aThis.toolbarDeck)
  1522.                             aThis.toggleNavigation(aShowFlag);
  1523.                         aThis.mToggleNavigationOnHoverTimer = null;
  1524.                     },
  1525.                     (
  1526.                         aDelay !== void(0) ? aDelay :
  1527.                             this.mIsToolbarHover ?
  1528.                                 SplitBrowser.subBrowserToolbarShowDelay :
  1529.                                 SplitBrowser.subBrowserToolbarHideDelay
  1530.                     ),
  1531.                     aShow,
  1532.                     this
  1533.                 );
  1534.             ]]></body>
  1535.         </method>
  1536.         <field name="mToggleNavigationOnHoverTimer">null</field>
  1537.  
  1538.         <method name="resetNavigation">
  1539.             <body><![CDATA[
  1540.                 if (this.getAttribute('toolbar-navigation') != 'true')
  1541.                     this.toggleNavigation(false);
  1542.             ]]></body>
  1543.         </method>
  1544.  
  1545.  
  1546.  
  1547.  
  1548.  
  1549.         <method name="setIcon">
  1550.             <parameter name="aURI"/>
  1551.             <body><![CDATA[
  1552.                 this.mIconURL = aURI;
  1553.                 this.updateIcon();
  1554.             ]]></body>
  1555.         </method>
  1556.  
  1557.         <method name="updateIcon">
  1558.             <body><![CDATA[
  1559.                 if (!this.mIsBusy && this.mIconURL) {
  1560.                     this.favicon.setAttribute('src', this.mIconURL);
  1561.                     this.vFavicon.setAttribute('src', this.mIconURL);
  1562.                     this.urlbarFavicon.setAttribute('src', this.mIconURL);
  1563.                 }
  1564.                 else {
  1565.                     this.favicon.removeAttribute('src');
  1566.                     this.vFavicon.removeAttribute('src');
  1567.                     this.urlbarFavicon.removeAttribute('src');
  1568.                 }
  1569.             ]]></body>
  1570.         </method>
  1571.  
  1572.         <method name="useDefaultIcon">
  1573.             <body><![CDATA[
  1574.                 if (this.browser.contentDocument instanceof ImageDocument) {
  1575.                     if (SplitBrowser.getPref('browser.chrome.site_icons')) {
  1576.                         try {
  1577.                             var sz = SplitBrowser.getPref('browser.chrome.image_icons.max_size');
  1578.                             if (!sz)
  1579.                                 return;
  1580.                             var req = this.browser.contentDocument.imageRequest;
  1581.                             if (!req || !req.image || req.image.width > sz || req.image.height > sz)
  1582.                                 return;
  1583.                             this.setIcon(this.browser.currentURI.spec);
  1584.                         }
  1585.                         catch (e) {
  1586.                         }
  1587.                     }
  1588.                 }
  1589.                 else if (this.shouldLoadFavIcon(this.browser.currentURI)) {
  1590.                     var url = this.browser.currentURI.prePath + '/favicon.ico';
  1591.                     if (!this.isIconKnownMissing(url))
  1592.                         this.setIcon(url);
  1593.                 }
  1594.             ]]></body>
  1595.         </method>
  1596.  
  1597.         <method name="shouldLoadFavIcon">
  1598.             <parameter name="aURI"/>
  1599.             <body><![CDATA[
  1600.                 return (
  1601.                     aURI &&
  1602.                     SplitBrowser.getPref('browser.chrome.site_icons') &&
  1603.                     SplitBrowser.getPref('browser.chrome.favicons') &&
  1604.                     ('schemeIs' in aURI) &&
  1605.                     (aURI.schemeIs('http') || aURI.schemeIs('https'))
  1606.                 );
  1607.             ]]></body>
  1608.         </method>
  1609.  
  1610.         <method name="addToMissedIconCache">
  1611.             <parameter name="aURI"/>
  1612.             <body><![CDATA[
  1613.                 var entry = this.openCacheEntry(aURI, Components.interfaces.nsICache.ACCESS_READ_WRITE);
  1614.                 if (!entry) return;
  1615.  
  1616.                 if (entry.accessGranted == Components.interfaces.nsICache.ACCESS_WRITE)
  1617.                     entry.setMetaDataElement('Icon', 'Missed');
  1618.                 entry.markValid();
  1619.                 entry.close();
  1620.             ]]></body>
  1621.         </method>
  1622.  
  1623.         <method name="openCacheEntry">
  1624.             <parameter name="aKey"/>
  1625.             <parameter name="aAccess"/>
  1626.             <body><![CDATA[
  1627.                 try {
  1628.                     if (!this.mMissedIconCache) {
  1629.                         var cacheService = Components.classes['@mozilla.org/network/cache-service;1'].getService(Components.interfaces.nsICacheService);
  1630.                         this.mMissedIconCache = cacheService.createSession('MissedIconCache', Components.interfaces.nsICache.STORE_ANYWHERE, true);
  1631.                         if (!this.mMissedIconCache) return null;
  1632.                     }
  1633.                     return this.mMissedIconCache.openCacheEntry(aKey, aAccess, true);
  1634.                 }
  1635.                 catch (e) {
  1636.                     return null;
  1637.                 }
  1638.             ]]></body>
  1639.         </method>
  1640.  
  1641.         <method name="isIconKnownMissing">
  1642.             <parameter name="aKey"/>
  1643.             <body><![CDATA[
  1644.                 var e = this.openCacheEntry(aKey, Components.interfaces.nsICache.ACCESS_READ);
  1645.                 if (e) {
  1646.                     e.close();
  1647.                     return true;
  1648.                 }
  1649.                 return false;
  1650.             ]]></body>
  1651.         </method>
  1652.  
  1653.         <method name="onLinkAdded">
  1654.             <parameter name="aEvent"/>
  1655.             <body><![CDATA[
  1656.                 if (!SplitBrowser.getPref('browser.chrome.site_icons')) return;
  1657.                 if (!aEvent.originalTarget.rel.match((/(?:^|\s)icon(?:\s|$)/i))) return;
  1658.  
  1659.                 var href = aEvent.originalTarget.href;
  1660.                 if (!href) return;
  1661.  
  1662.                 const nsIContentPolicy = Components.interfaces.nsIContentPolicy;
  1663.                 try {
  1664.                     var contentPolicy = Components.classes['@mozilla.org/layout/content-policy;1'].getService(nsIContentPolicy);
  1665.                 }
  1666.                 catch(e) {
  1667.                     return;
  1668.                 }
  1669.  
  1670.                 const secMan = Components.classes['@mozilla.org/scriptsecuritymanager;1'].getService(Components.interfaces.nsIScriptSecurityManager);
  1671.                 const ioService = Components.classes['@mozilla.org/network/io-service;1'].getService(Components.interfaces.nsIIOService);
  1672.                 const targetDoc = aEvent.target.ownerDocument;
  1673.                 var uri = ioService.newURI(href, targetDoc.characterSet, null);
  1674.                 var origURI = ioService.newURI(targetDoc.documentURI, targetDoc.characterSet, null);
  1675.  
  1676.                 const nsIScriptSecMan = Components.interfaces.nsIScriptSecurityManager;
  1677.                 try {
  1678.                     const aboutNeterr = 'about:neterror?';
  1679.                     if (origURI.spec.substr(0, aboutNeterr.length) != aboutNeterr ||
  1680.                         !uri.schemeIs('chrome'))
  1681.                         secMan.checkLoadURI(origURI, uri, nsIScriptSecMan.DISALLOW_SCRIPT);
  1682.                 }
  1683.                 catch(e) {
  1684.                     return;
  1685.                 }
  1686.  
  1687.                 if (contentPolicy.shouldLoad(
  1688.                         nsIContentPolicy.TYPE_IMAGE,
  1689.                         uri,
  1690.                         origURI,
  1691.                         aEvent.target,
  1692.                         aEvent.target.type,
  1693.                         null
  1694.                     ) != nsIContentPolicy.ACCEPT)
  1695.                     return;
  1696.  
  1697.                 if (targetDoc == this.browser.contentDocument)
  1698.                     this.setIcon(href);
  1699.             ]]></body>
  1700.         </method>
  1701.  
  1702.  
  1703.  
  1704.         <field name="pageDNDObserver"><![CDATA[
  1705.         ({
  1706.             mOwner : this,
  1707.  
  1708.             onDragStart : function (aEvent, aXferData, aDragAction)
  1709.             {
  1710.                 var value = this.mOwner.src;
  1711.                 if (!value) return;
  1712.  
  1713.                 var urlString = value + '\n' + this.mOwner.browser.contentDocument.title;
  1714.                 var htmlString = '<a href="' + value + '">' + value + '</a>';
  1715.  
  1716.                 aXferData.data = new TransferData();
  1717.  
  1718.                 aXferData.data.addDataForFlavour('application/x-moz-splitbrowser',
  1719.                     'subbrowser\n'+
  1720.                     {
  1721.                         id     : this.mOwner.id,
  1722.                         uri    : value,
  1723.                         width  : this.mOwner.boxObject.width,
  1724.                         height : this.mOwner.boxObject.height
  1725.                     }.toSource()
  1726.                 );
  1727.  
  1728.                 aXferData.data.addDataForFlavour('text/x-moz-url', urlString);
  1729.                 aXferData.data.addDataForFlavour('text/unicode', value);
  1730.                 aXferData.data.addDataForFlavour('text/plain', value);
  1731.                 aXferData.data.addDataForFlavour('text/html', htmlString);
  1732.  
  1733.                 aDragAction.action =
  1734.                     Components.interfaces.nsIDragService.DRAGDROP_ACTION_COPY |
  1735.                     Components.interfaces.nsIDragService.DRAGDROP_ACTION_MOVE |
  1736.                     Components.interfaces.nsIDragService.DRAGDROP_ACTION_LINK;
  1737.             },
  1738.  
  1739.             onDragOver : function(aEvent, aFlavour, aDragSession)
  1740.             {
  1741.             },
  1742.  
  1743.             canDrop : function(aEvent, aDragSession)
  1744.             {
  1745.                 return (
  1746.                         SplitBrowser.getSubBrowserFromChild(aDragSession.sourceNode) != this.mOwner ||
  1747.                         (
  1748.                             !SplitBrowser.isEventFiredOnTabbar(aEvent, this.mOwner.browser) &&
  1749.                             !this.mOwner.isEventFiredOnToolbar(aEvent)
  1750.                         )
  1751.                     );
  1752.             },
  1753.  
  1754.             onDrop : function (aEvent, aXferData, aDragSession)
  1755.             {
  1756.                 // events on the tab bar should be handled by tabbrowser's "_onDrop" method
  1757.                 if (SplitBrowser.isEventFiredOnTabbar(aEvent, this.mOwner.browser))
  1758.                     return;
  1759.  
  1760.                 // ignore self-drop onto the toolbar (why we cannot prevent it by "canDrop()"...?)
  1761.                 if (SplitBrowser.getSubBrowserFromChild(aDragSession.sourceNode) == this.mOwner &&
  1762.                     this.mOwner.isEventFiredOnToolbar(aEvent))
  1763.                     return;
  1764.  
  1765.                 aEvent.preventDefault();
  1766.                 aEvent.stopPropagation();
  1767.  
  1768.                 var uri = SplitBrowser.getURIFromDragData(aXferData, aDragSession, aEvent);
  1769.                 if (!uri) return;
  1770.  
  1771.                 // fallback for Linux
  1772.                 // in Linux, "dragdrop" event doesn't fire on the button.
  1773.                 var forceCheck = aEvent.ctrlKey || aXferData.flavour.contentType == 'application/x-moz-splitbrowser';
  1774.                 var check = this.mOwner.checkEventFiredOnEdge(aEvent);
  1775.                 if (!check) return;
  1776.  
  1777.                 if (
  1778.                     (forceCheck || SplitBrowser.isLinux) &&
  1779.                     SplitBrowser.addButton.targetSubBrowser == this.mOwner &&
  1780.                     (
  1781.                         check.inTopArea ||
  1782.                         check.inBottomArea ||
  1783.                         check.inLeftArea ||
  1784.                         check.inRightArea
  1785.                     ) &&
  1786.                     (
  1787.                         this.mOwner.browser.localName != 'tabbrowser' ||
  1788.                         !this.mOwner.isEventFiredOnToolbar(aEvent)
  1789.                     )
  1790.                     ) {
  1791.                     var tab = SplitBrowser.getTabFromChild(aDragSession.sourceNode);
  1792.                     var tabbrowser = SplitBrowser.getTabBrowserFromChild(tab);
  1793.                     if (!tabbrowser) tab = null;
  1794.                     SplitBrowser.fireSubBrowserAddRequestEventFromButton(
  1795.                         tab || uri,
  1796.                         SplitBrowser.isAccelKeyPressed(aEvent)
  1797.                     );
  1798.                     return;
  1799.                 }
  1800.  
  1801.                 if (SplitBrowser.performDropOnTabBrowser(arguments, this.mOwner.browser)) {
  1802.                     return;
  1803.                 }
  1804.  
  1805.                 if (this.mOwner.browser.localName == 'tabbrowser' &&
  1806.                     this.mOwner.isEventFiredOnToolbar(aEvent)) {
  1807.                     this.mOwner.browser.selectedTab = this.mOwner.browser.addTab(uri);
  1808.                 }
  1809.                 else {
  1810.                     this.mOwner.load(uri);
  1811.                 }
  1812.             },
  1813.  
  1814.             getSupportedFlavours : function ()
  1815.             {
  1816.                 var flavourSet = new FlavourSet();
  1817.                 flavourSet.appendFlavour('application/x-moz-splitbrowser');
  1818.                 flavourSet.appendFlavour('application/x-moz-tabbrowser-tab');
  1819.                 flavourSet.appendFlavour('text/x-moz-text-internal');
  1820.                 flavourSet.appendFlavour('text/x-moz-url');
  1821.                 flavourSet.appendFlavour('text/unicode');
  1822.                 flavourSet.appendFlavour('text/plain');
  1823.                 flavourSet.appendFlavour('application/x-moz-file', 'nsIFile');
  1824.                 return flavourSet;
  1825.             }
  1826.         })
  1827.         ]]></field>
  1828.         <method name="isEventFiredOnToolbar">
  1829.             <parameter name="aEvent"/>
  1830.             <body><![CDATA[
  1831.                 var box = this.toolbar.boxObject;
  1832.                 return (
  1833.                     box.screenX <= aEvent.screenX &&
  1834.                     box.screenX + box.width >= aEvent.screenX &&
  1835.                     box.screenY <= aEvent.screenY &&
  1836.                     box.screenY + box.height >= aEvent.screenY
  1837.                     );
  1838.             ]]></body>
  1839.         </method>
  1840.  
  1841.  
  1842.         <method name="openNewTab">
  1843.             <body><![CDATA[
  1844.                 var b = this.browser;
  1845.                 var t = b.addTab('about:blank');
  1846.                 this.toggleNavigation(true);
  1847.                 window.setTimeout(function(aUrlbar) {
  1848.                     b.selectedTab = t;
  1849.                     window.setTimeout(function(aUrlbar) {
  1850.                         aUrlbar.value = '';
  1851.                         aUrlbar.focus();
  1852.                     }, 0, aUrlbar);
  1853.                 }, 0, this.urlbar);
  1854.             ]]></body>
  1855.         </method>
  1856.  
  1857.         <method name="newUpdateCurrentBrowser">
  1858.             <body><![CDATA[
  1859.                 var result = this.__splitbrowser__updateCurrentBrowser.apply(this, arguments);
  1860.  
  1861.                 if (this.parentSubBrowser.focused) {
  1862.                     SplitBrowser.mainBrowserBox.blur();
  1863.                 }
  1864.                 else {
  1865.                     var node = SplitBrowser.activeSubBrowser;
  1866.                     this.parentSubBrowser.blur();
  1867.                     if (node)
  1868.                         node.focus();
  1869.                 }
  1870.  
  1871.                 return result;
  1872.             ]]></body>
  1873.         </method>
  1874.  
  1875.         <method name="addProgressListener">
  1876.             <parameter name="aTab"/>
  1877.             <body><![CDATA[
  1878.                 var browser = aTab ? this.browser.getBrowserForTab(aTab) : this.browser ;
  1879.                 if (browser.__splitbrowser__tabProgressListener) return;
  1880.  
  1881.                 var filter = Components.classes['@mozilla.org/appshell/component/browser-status-filter;1'].createInstance(Components.interfaces.nsIWebProgress);
  1882.                 var listener = this.createProgressListener(aTab, browser);
  1883.                 filter.addProgressListener(listener, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
  1884.                 browser.webProgress.addProgressListener(filter, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
  1885.  
  1886.                 browser.__splitbrowser__tabProgressListener = listener;
  1887.                 browser.__splitbrowser__tabProgressFilter = filter;
  1888.             ]]></body>
  1889.         </method>
  1890.  
  1891.         <method name="removeProgressListener">
  1892.             <parameter name="aTab"/>
  1893.             <body><![CDATA[
  1894.                 var browser = aTab ? this.browser.getBrowserForTab(aTab) : this.browser ;
  1895.                 if (!browser.__splitbrowser__tabProgressListener) return;
  1896.  
  1897.                 delete browser.__splitbrowser__tabProgressListener.mOwner;
  1898.                 delete browser.__splitbrowser__tabProgressListener.mTab;
  1899.                 delete browser.__splitbrowser__tabProgressListener.mBrowser;
  1900.  
  1901.                 browser.webProgress.removeProgressListener(browser.__splitbrowser__tabProgressFilter);
  1902.                 browser.__splitbrowser__tabProgressFilter.removeProgressListener(browser.__splitbrowser__tabProgressListener);
  1903.  
  1904.                 delete browser.__splitbrowser__tabProgressListener;
  1905.                 delete browser.__splitbrowser__tabProgressFilter;
  1906.             ]]></body>
  1907.         </method>
  1908.  
  1909.         <method name="createProgressListener">
  1910.             <parameter name="aTab"/>
  1911.             <parameter name="aBrowser"/>
  1912.             <body><![CDATA[
  1913.             return {
  1914.  
  1915.             mOwner         : this,
  1916.             mTab           : aTab,
  1917.             mBrowser       : aBrowser,
  1918.             mTotalProgress : 0,
  1919.  
  1920.             onProgressChange: function (aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress)
  1921.             {
  1922.                 if (this.mOwner.isIeTab) {
  1923.                     var ietab = this.mOwner.getIETabOf(this.mBrowser);
  1924.                     aCurTotalProgress = ietab.progress;
  1925.                     aMaxTotalProgress = (aCurTotalProgress == -1 ? -1 : 100);
  1926.                 }
  1927.  
  1928.                 this.mTotalProgress = aMaxTotalProgress ? aCurTotalProgress / aMaxTotalProgress : 0;
  1929.                 if (this.mTab)
  1930.                     this.mTab.mSubbrowserTabTotalProgress = this.mTotalProgress;
  1931.  
  1932.                 if (this.mTab && this.mTab != this.mOwner.browser.mCurrentTab) return;
  1933.  
  1934.                 this.mOwner.mTotalProgress = this.mTotalProgress;
  1935.                 this.mOwner.updateToolbarForCurrentTab();
  1936.             },
  1937.  
  1938.             onStateChange : function(aWebProgress, aRequest, aStateFlags, aStatus)
  1939.             {
  1940.                 if (this.mTab && this.mTab != this.mOwner.browser.mCurrentTab) return;
  1941.  
  1942.                 const nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
  1943.                 if (
  1944.                     aStateFlags & nsIWebProgressListener.STATE_START &&
  1945.                     aStateFlags & nsIWebProgressListener.STATE_IS_NETWORK
  1946.                     ) {
  1947.                     this.mOwner.mIsBusy = true;
  1948.                     this.mOwner.updateToolbarForCurrentTab();
  1949.                 }
  1950.                 else if (
  1951.                     aStateFlags & nsIWebProgressListener.STATE_STOP &&
  1952.                     aStateFlags & nsIWebProgressListener.STATE_IS_NETWORK
  1953.                     ) {
  1954.                     this.mOwner.mIsBusy = false;
  1955.                     this.mOwner.updateToolbarForCurrentTab();
  1956.                 }
  1957.             },
  1958.  
  1959.             onLocationChange : function(aWebProgress, aRequest, aLocation)
  1960.             {
  1961.                 if (this.mTab && this.mTab != this.mOwner.browser.mCurrentTab) return;
  1962.  
  1963.                 this.mOwner.urlbar.value = aLocation.spec;
  1964.                 this.mOwner.setAttribute('src', aLocation.spec);
  1965.  
  1966.                 if (aWebProgress.DOMWindow == this.mBrowser.contentWindow &&
  1967.                     aWebProgress.isLoadingDocument)
  1968.                     this.mOwner.setIcon(null);
  1969.             },
  1970.  
  1971.             onStatusChange : function(aWebProgress, aRequest, aStatus, aMessage)
  1972.             {
  1973.             },
  1974.  
  1975.             onSecurityChange : function(aWebProgress, aRequest, aState)
  1976.             {
  1977.             },
  1978.  
  1979.             QueryInterface : function(aIID)
  1980.             {
  1981.                 if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
  1982.                     aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
  1983.                     aIID.equals(Components.interfaces.nsISupports))
  1984.                     return this;
  1985.                 throw Components.results.NS_NOINTERFACE;
  1986.             }
  1987.  
  1988.             };
  1989.             ]]></body>
  1990.         </method>
  1991.  
  1992.         <constructor><![CDATA[
  1993.             var b = this.browser;
  1994.             if (b.nextSibling && b.nextSibling.localName == 'browser')
  1995.                 b.parentNode.removeChild(b.nextSibling);
  1996.             if (b.previousSibling && b.previousSibling.localName == 'tabbrowser')
  1997.                 b.parentNode.removeChild(b.previousSibling);
  1998.  
  1999.             b.parentSubBrowser = this;
  2000.  
  2001.             if (SplitBrowser.getPref('splitbrowser.show.toolbar.navigation.always')) {
  2002.                 this.setAttribute('toolbar-navigation', true);
  2003.                 this.toggleNavigation(true);
  2004.             }
  2005.  
  2006.             if (b.localName == 'tabbrowser') {
  2007.                 eval('b.addTab = '+b.addTab.toSource().replace(
  2008.                     'if (!this.mTabChangedListenerAdded) {',
  2009.                     '$& this.attrChangedListener = attrChanged;'
  2010.                 ));
  2011.                 b.__splitbrowser__updateCurrentBrowser = b.updateCurrentBrowser;
  2012.                 b.updateCurrentBrowser = this.newUpdateCurrentBrowser;
  2013.  
  2014.                 SplitBrowser.updateTabBrowser(b);
  2015.  
  2016.                 window.setTimeout(this.mDelayedTabbrowserStartup, 0, this);
  2017.             }
  2018.             else {
  2019.                 this.addProgressListener(null);
  2020.  
  2021.                 window.setTimeout(this.mDelayedBrowserStartup, 0, this);
  2022.  
  2023.                 if (this.getAttribute('src'))
  2024.                     this.load(this.getAttribute('src'));
  2025.             }
  2026.  
  2027.             var os = Components.classes['@mozilla.org/observer-service;1']
  2028.                         .getService(Components.interfaces.nsIObserverService);
  2029.             os.addObserver(this.syncScrollObserver, 'subbrowser:syncScroll', false);
  2030.         ]]></constructor>
  2031.         <destructor><![CDATA[
  2032.             var os = Components.classes['@mozilla.org/observer-service;1']
  2033.                         .getService(Components.interfaces.nsIObserverService);
  2034.             os.removeObserver(this.syncScrollObserver, 'subbrowser:syncScroll');
  2035.         ]]></destructor>
  2036.  
  2037.         <method name="mDelayedBrowserStartup">
  2038.             <parameter name="aThis"/>
  2039.             <body><![CDATA[
  2040.                 aThis.blur();
  2041.                 aThis.mUpdateToolbarMode();
  2042.  
  2043.                 var newEvent = document.createEvent('Events');
  2044.                 newEvent.initEvent('SubBrowserAdded', false, true);
  2045.                 aThis.dispatchEvent(newEvent);
  2046.             ]]></body>
  2047.         </method>
  2048.         <method name="mDelayedTabbrowserStartup">
  2049.             <parameter name="aThis"/>
  2050.             <body><![CDATA[
  2051.             aThis.mDelayedBrowserStartup(aThis);
  2052.  
  2053.             var b = aThis.browser;
  2054.             var t = SplitBrowser.getFirstTab(b);
  2055.             aThis.addProgressListener(t);
  2056.  
  2057.             var autoHide = SplitBrowser.getPref('splitbrowser.tabs.autoHide');
  2058.             if (b.mTabs.length == 1)
  2059.                 b.setStripVisibilityTo(!autoHide);
  2060.  
  2061.             b = b.getBrowserForTab(t);
  2062.             b.webNavigation.sessionHistory = Components.classes['@mozilla.org/browser/shistory;1'].createInstance(Components.interfaces.nsISHistory);
  2063.  
  2064.             var os = Components.classes['@mozilla.org/observer-service;1'].getService(Components.interfaces.nsIObserverService);
  2065.             os.addObserver(b, 'browser:purge-session-history', false);
  2066.             b.removeAttribute('disablehistory');
  2067.             b.docShell.QueryInterface(Components.interfaces.nsIDocShellHistory).useGlobalHistory = true;
  2068.  
  2069.             if (aThis.getAttribute('src'))
  2070.                 aThis.load(aThis.getAttribute('src'));
  2071.             ]]></body>
  2072.         </method>
  2073.  
  2074.  
  2075.         <method name="destroy">
  2076.             <parameter name="aPreventRestore"/>
  2077.             <body><![CDATA[
  2078.                 var state = !aPreventRestore ? SplitBrowser.getContainerState(this.parentContainer) : null ;
  2079.                 if (state) {
  2080.                     let box = this.boxObject;
  2081.                     let main = gBrowser.boxObject;
  2082.                     if (window.getComputedStyle(this.parentContainer.parentNode, null).getPropertyValue('-moz-box-orient') == 'horizontal') {
  2083.                         if (box.screenX + box.width < main.screenX)
  2084.                             state.position = SplitBrowser.POSITION_LEFT;
  2085.                         else
  2086.                             state.position = SplitBrowser.POSITION_RIGHT;
  2087.                     }
  2088.                     else {
  2089.                         if (box.screenY + box.height < main.screenY)
  2090.                             state.position = SplitBrowser.POSITION_TOP;
  2091.                         else
  2092.                             state.position = SplitBrowser.POSITION_BOTTOM;
  2093.                     }
  2094.                     state.width = box.width;
  2095.                     state.height = box.height;
  2096.                     state.collapsed = this.contentCollapsed;
  2097.                 }
  2098.                 var title = this.title.getAttribute('value');
  2099.                 var icon  = this.mIconURL;
  2100.  
  2101.                 if (this.focused) {
  2102.                     gBrowser.contentWindow.focus();
  2103.                 }
  2104.                 this.blur();
  2105.  
  2106.                 var b = this.browser;
  2107.                 if (b.localName == 'tabbrowser') {
  2108.                     if (b.mCurrentBrowser.getAttribute('type') == 'content-primary')
  2109.                         document.getElementById('appcontent').contentWrapper.focus();
  2110.  
  2111.                     b.mCurrentBrowser.removeAttribute('type');
  2112.                     b.mCurrentBrowser.setAttribute('type', 'content');
  2113.                     var tabs = SplitBrowser.getTabs(b);
  2114.                     for (var i = 0, maxi = tabs.snapshotLength; i < maxi; i++)
  2115.                     {
  2116.                         this.removeProgressListener(tabs.snapshotItem(i));
  2117.                         try {
  2118.                             b.browsers[i].destroy();
  2119.                             b.browsers[i].removeEventListener('DOMTitleChanged', b.onTitleChanged, true);
  2120.                         }
  2121.                         catch(e) {
  2122.                         }
  2123.                     }
  2124.                     try {
  2125.                         document.removeEventListener('keypress', b._keyEventHandler, false);
  2126.                         if (b.attrChangedListener)
  2127.                             b.mTabBox.addEventListener('DOMAttrModified', b.attrChangedListener, false);
  2128.                         window.removeEventListener('resize', b, false);
  2129.                     }
  2130.                     catch(e) {
  2131.                     }
  2132.                     try {
  2133.                         window.removeEventListener('resize', b.mTabContainer, false);
  2134.                         b.mStrip.removeEventListener('overflow', b.mTabContainer, false);
  2135.                         b.mStrip.removeEventListener('underflow', b.mTabContainer, false);
  2136.                     }
  2137.                     catch(e) {
  2138.                     }
  2139.                 }
  2140.                 else {
  2141.                     if (b.getAttribute('type') == 'content-primary')
  2142.                         document.getElementById('appcontent').contentWrapper.focus();
  2143.  
  2144.                     b.removeAttribute('type');
  2145.                     b.setAttribute('type', 'content');
  2146.                     this.removeProgressListener();
  2147.  
  2148.                     try {
  2149.                         b.destroy();
  2150.                     }
  2151.                     catch(e) {
  2152.                     }
  2153.                 }
  2154.  
  2155.                 var newEvent = document.createEvent('Events');
  2156.                 newEvent.initEvent('SubBrowserRemoved', false, true);
  2157.                 newEvent.title = title || '';
  2158.                 newEvent.icon  = icon || '';
  2159.                 newEvent.state = state ? state.toSource() : '' ;
  2160.                 document.documentElement.dispatchEvent(newEvent);
  2161.  
  2162.                 b.parentSubBrowser = null;
  2163.  
  2164.                 b.parentNode.removeChild(b);
  2165.             ]]></body>
  2166.         </method>
  2167.  
  2168.  
  2169.         <method name="onTabSelect">
  2170.             <parameter name="aEvent"/>
  2171.             <body><![CDATA[
  2172.                 this.updateToolbarForCurrentTab(true);
  2173.  
  2174.                 var newEvent = document.createEvent('Events');
  2175.                 newEvent.initEvent('SubBrowserTabSelect', false, true);
  2176.                 newEvent.targetTab = this.browser.selectedTab;
  2177.                 this.dispatchEvent(newEvent);
  2178.             ]]></body>
  2179.         </method>
  2180.  
  2181.         <method name="onTabOpen">
  2182.             <parameter name="aEvent"/>
  2183.             <body><![CDATA[
  2184.                 this.addProgressListener(aEvent.originalTarget);
  2185.             ]]></body>
  2186.         </method>
  2187.  
  2188.         <method name="onTabClose">
  2189.             <parameter name="aEvent"/>
  2190.             <body><![CDATA[
  2191.                 this.removeProgressListener(aEvent.originalTarget);
  2192.                 if (SplitBrowser.getTabs(this.browser).snapshotLength <= 2) {
  2193.                     this.browser.setStripVisibilityTo(!SplitBrowser.getPref('splitbrowser.tabs.autoHide'));
  2194.                 }
  2195.             ]]></body>
  2196.         </method>
  2197.  
  2198.         <method name="mUpdateToolbarMode">
  2199.             <body><![CDATA[
  2200.                 var c = this.flexibleParent;
  2201.                 while (c && c.parentNode && !c.splitterDragging)
  2202.                     c = c.parentNode;
  2203.                 if (c && c == document) c = null;
  2204.  
  2205.                 var collapse;
  2206.  
  2207.                 var toolbarShown = SplitBrowser.getPref('splitbrowser.show.toolbar.always');
  2208.  
  2209.                 if (this.boxObject.width <= this.minSize) {
  2210.                     if (this.boxObject.height <= this.minSize) {
  2211.                         this.setAttribute('toolbar-mode', 'horizontal');
  2212.                         if (c && toolbarShown) c.setAttribute('maxheight', 0);
  2213.                     }
  2214.                     else {
  2215.                         this.setAttribute('toolbar-mode', 'vertical');
  2216.                         if (c && toolbarShown) c.setAttribute('maxwidth', 0);
  2217.                     }
  2218.                     collapse = true;
  2219.                 }
  2220.                 else {
  2221.                     this.setAttribute('toolbar-mode', 'horizontal');
  2222.                     if (this.boxObject.height <= this.minSize) {
  2223.                         if (c && toolbarShown) c.setAttribute('maxheight', 0);
  2224.                         collapse = true;
  2225.                     }
  2226.                     else {
  2227.                         collapse = false;
  2228.                     }
  2229.                 }
  2230.  
  2231.                 if (collapse) {
  2232.                     if (!this.contentCollapsed)
  2233.                         this.collapse();
  2234.  
  2235.                     this.setAttribute('content-collapsed', 'true');
  2236.                     if (this.getAttribute('toolbar-navigation') == 'true')
  2237.                         this.toggleNavigation(false);
  2238.  
  2239.                     var newEvent = document.createEvent('Events');
  2240.                     newEvent.initEvent('SubBrowserContentCollapsed', false, true);
  2241.                     document.documentElement.dispatchEvent(newEvent);
  2242.                 }
  2243.                 else {
  2244.                     this.removeAttribute('content-collapsed');
  2245.                     if (this.getAttribute('toolbar-navigation') == 'true')
  2246.                         this.toggleNavigation(true);
  2247.  
  2248.                     var newEvent = document.createEvent('Events');
  2249.                     newEvent.initEvent('SubBrowserContentExpanded', false, true);
  2250.                     document.documentElement.dispatchEvent(newEvent);
  2251.                 }
  2252.             ]]></body>
  2253.         </method>
  2254.  
  2255.     </implementation>
  2256.  
  2257.     <handlers>
  2258.         <handler event="DOMLinkAdded" phase="capturing"
  2259.             action="this.onLinkAdded(event);"/>
  2260.  
  2261.         <handler event="resize"
  2262.             action="this.mUpdateToolbarMode();"/>
  2263.  
  2264.         <handler event="click"
  2265.             action="if (!this.contentCollapsed && !this.focused) this.browser.contentWindow.focus();"/>
  2266.  
  2267.         <handler event="DOMWindowClose" phase="capturing"><![CDATA[
  2268.             if (
  2269.                 (
  2270.                     this.browser.localName != 'tabbrowser' ||
  2271.                     this.browser.browsers.length == 1
  2272.                 ) &&
  2273.                 event.target == this.browser.contentWindow
  2274.                 ) {
  2275.                 event.preventDefault();
  2276.                 this.close();
  2277.             }
  2278.         ]]></handler>
  2279.  
  2280.         <handler event="blur" phase="capturing"><![CDATA[
  2281.             if (event.originalTarget.ownerDocument == document &&
  2282.                 event.originalTarget.localName == 'input') {
  2283.                 this.isUrlbarFocused = false;
  2284.                 this.toggleNavigationOnHover(false);
  2285.             }
  2286.         ]]></handler>
  2287.  
  2288.         <handler event="TabSelect" action="this.onTabSelect(event);"/>
  2289.         <handler event="TabOpen" action="this.onTabOpen(event);"/>
  2290.         <handler event="TabClose" action="this.onTabClose(event);"/>
  2291.  
  2292.     </handlers>
  2293. </binding>
  2294.  
  2295.  
  2296. </bindings>
  2297.